]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] pcsp: add description
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
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,
368c7a95 204 ALC883_CLEVO_M720R,
9c7f852e
TI
205 ALC883_AUTO,
206 ALC883_MODEL_LAST,
207};
208
df694daa
KY
209/* for GPIO Poll */
210#define GPIO_MASK 0x03
211
1da177e4
LT
212struct alc_spec {
213 /* codec parameterization */
df694daa 214 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
215 unsigned int num_mixers;
216
df694daa 217 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
218 * don't forget NULL
219 * termination!
e9edcee0
TI
220 */
221 unsigned int num_init_verbs;
1da177e4 222
16ded525 223 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
224 struct hda_pcm_stream *stream_analog_playback;
225 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
226 struct hda_pcm_stream *stream_analog_alt_playback;
227 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 228
f12ab1e0 229 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
230 struct hda_pcm_stream *stream_digital_playback;
231 struct hda_pcm_stream *stream_digital_capture;
232
233 /* playback */
16ded525
TI
234 struct hda_multi_out multiout; /* playback set-up
235 * max_channels, dacs must be set
236 * dig_out_nid and hp_nid are optional
237 */
6330079f 238 hda_nid_t alt_dac_nid;
1da177e4
LT
239
240 /* capture */
241 unsigned int num_adc_nids;
242 hda_nid_t *adc_nids;
e1406348 243 hda_nid_t *capsrc_nids;
16ded525 244 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
245
246 /* capture source */
a1e8d2da 247 unsigned int num_mux_defs;
1da177e4
LT
248 const struct hda_input_mux *input_mux;
249 unsigned int cur_mux[3];
250
251 /* channel model */
d2a6d7dc 252 const struct hda_channel_mode *channel_mode;
1da177e4 253 int num_channel_mode;
4e195a7b 254 int need_dac_fix;
1da177e4
LT
255
256 /* PCM information */
4c5186ed 257 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 258
e9edcee0
TI
259 /* dynamic controls, init_verbs and input_mux */
260 struct auto_pin_cfg autocfg;
261 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 262 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 263 struct hda_input_mux private_imux;
41923e44 264 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 265
ae6b813a
TI
266 /* hooks */
267 void (*init_hook)(struct hda_codec *codec);
268 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
269
834be88d
TI
270 /* for pin sensing */
271 unsigned int sense_updated: 1;
272 unsigned int jack_present: 1;
bec15c3a 273 unsigned int master_sw: 1;
cb53c626 274
2134ea4f
TI
275 /* for virtual master */
276 hda_nid_t vmaster_nid;
cb53c626
TI
277#ifdef CONFIG_SND_HDA_POWER_SAVE
278 struct hda_loopback_check loopback;
279#endif
df694daa
KY
280};
281
282/*
283 * configuration template - to be copied to the spec instance
284 */
285struct alc_config_preset {
9c7f852e
TI
286 struct snd_kcontrol_new *mixers[5]; /* should be identical size
287 * with spec
288 */
df694daa
KY
289 const struct hda_verb *init_verbs[5];
290 unsigned int num_dacs;
291 hda_nid_t *dac_nids;
292 hda_nid_t dig_out_nid; /* optional */
293 hda_nid_t hp_nid; /* optional */
294 unsigned int num_adc_nids;
295 hda_nid_t *adc_nids;
e1406348 296 hda_nid_t *capsrc_nids;
df694daa
KY
297 hda_nid_t dig_in_nid;
298 unsigned int num_channel_mode;
299 const struct hda_channel_mode *channel_mode;
4e195a7b 300 int need_dac_fix;
a1e8d2da 301 unsigned int num_mux_defs;
df694daa 302 const struct hda_input_mux *input_mux;
ae6b813a
TI
303 void (*unsol_event)(struct hda_codec *, unsigned int);
304 void (*init_hook)(struct hda_codec *);
cb53c626
TI
305#ifdef CONFIG_SND_HDA_POWER_SAVE
306 struct hda_amp_list *loopbacks;
307#endif
1da177e4
LT
308};
309
1da177e4
LT
310
311/*
312 * input MUX handling
313 */
9c7f852e
TI
314static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
315 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
316{
317 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
318 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
319 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
320 if (mux_idx >= spec->num_mux_defs)
321 mux_idx = 0;
322 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
323}
324
9c7f852e
TI
325static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
326 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
327{
328 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
329 struct alc_spec *spec = codec->spec;
330 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
331
332 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
333 return 0;
334}
335
9c7f852e
TI
336static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
338{
339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
340 struct alc_spec *spec = codec->spec;
341 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da 342 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
e1406348
TI
343 hda_nid_t nid = spec->capsrc_nids ?
344 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
a1e8d2da 345 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
e1406348 346 nid, &spec->cur_mux[adc_idx]);
1da177e4
LT
347}
348
e9edcee0 349
1da177e4
LT
350/*
351 * channel mode setting
352 */
9c7f852e
TI
353static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
354 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
355{
356 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
357 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
358 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
359 spec->num_channel_mode);
1da177e4
LT
360}
361
9c7f852e
TI
362static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
363 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
364{
365 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
366 struct alc_spec *spec = codec->spec;
d2a6d7dc 367 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
368 spec->num_channel_mode,
369 spec->multiout.max_channels);
1da177e4
LT
370}
371
9c7f852e
TI
372static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
374{
375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
376 struct alc_spec *spec = codec->spec;
4e195a7b
TI
377 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
378 spec->num_channel_mode,
379 &spec->multiout.max_channels);
bd2033f2 380 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
381 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
382 return err;
1da177e4
LT
383}
384
a9430dd8 385/*
4c5186ed
JW
386 * Control the mode of pin widget settings via the mixer. "pc" is used
387 * instead of "%" to avoid consequences of accidently treating the % as
388 * being part of a format specifier. Maximum allowed length of a value is
389 * 63 characters plus NULL terminator.
7cf51e48
JW
390 *
391 * Note: some retasking pin complexes seem to ignore requests for input
392 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
393 * are requested. Therefore order this list so that this behaviour will not
394 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
395 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
396 * March 2006.
4c5186ed
JW
397 */
398static char *alc_pin_mode_names[] = {
7cf51e48
JW
399 "Mic 50pc bias", "Mic 80pc bias",
400 "Line in", "Line out", "Headphone out",
4c5186ed
JW
401};
402static unsigned char alc_pin_mode_values[] = {
7cf51e48 403 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
404};
405/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
406 * in the pin being assumed to be exclusively an input or an output pin. In
407 * addition, "input" pins may or may not process the mic bias option
408 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
409 * accept requests for bias as of chip versions up to March 2006) and/or
410 * wiring in the computer.
a9430dd8 411 */
a1e8d2da
JW
412#define ALC_PIN_DIR_IN 0x00
413#define ALC_PIN_DIR_OUT 0x01
414#define ALC_PIN_DIR_INOUT 0x02
415#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
416#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 417
a1e8d2da 418/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
419 * For each direction the minimum and maximum values are given.
420 */
a1e8d2da 421static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
422 { 0, 2 }, /* ALC_PIN_DIR_IN */
423 { 3, 4 }, /* ALC_PIN_DIR_OUT */
424 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
425 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
426 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
427};
428#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
429#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
430#define alc_pin_mode_n_items(_dir) \
431 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
432
9c7f852e
TI
433static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
434 struct snd_ctl_elem_info *uinfo)
a9430dd8 435{
4c5186ed
JW
436 unsigned int item_num = uinfo->value.enumerated.item;
437 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
438
439 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 440 uinfo->count = 1;
4c5186ed
JW
441 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
442
443 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
444 item_num = alc_pin_mode_min(dir);
445 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
446 return 0;
447}
448
9c7f852e
TI
449static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
450 struct snd_ctl_elem_value *ucontrol)
a9430dd8 451{
4c5186ed 452 unsigned int i;
a9430dd8
JW
453 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
454 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 455 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 456 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
457 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
458 AC_VERB_GET_PIN_WIDGET_CONTROL,
459 0x00);
a9430dd8 460
4c5186ed
JW
461 /* Find enumerated value for current pinctl setting */
462 i = alc_pin_mode_min(dir);
9c7f852e 463 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 464 i++;
9c7f852e 465 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
466 return 0;
467}
468
9c7f852e
TI
469static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
a9430dd8 471{
4c5186ed 472 signed int change;
a9430dd8
JW
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
475 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
476 long val = *ucontrol->value.integer.value;
9c7f852e
TI
477 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
478 AC_VERB_GET_PIN_WIDGET_CONTROL,
479 0x00);
a9430dd8 480
f12ab1e0 481 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
482 val = alc_pin_mode_min(dir);
483
484 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
485 if (change) {
486 /* Set pin mode to that requested */
82beb8fd
TI
487 snd_hda_codec_write_cache(codec, nid, 0,
488 AC_VERB_SET_PIN_WIDGET_CONTROL,
489 alc_pin_mode_values[val]);
cdcd9268
JW
490
491 /* Also enable the retasking pin's input/output as required
492 * for the requested pin mode. Enum values of 2 or less are
493 * input modes.
494 *
495 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
496 * reduces noise slightly (particularly on input) so we'll
497 * do it. However, having both input and output buffers
498 * enabled simultaneously doesn't seem to be problematic if
499 * this turns out to be necessary in the future.
cdcd9268
JW
500 */
501 if (val <= 2) {
47fd830a
TI
502 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
503 HDA_AMP_MUTE, HDA_AMP_MUTE);
504 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
505 HDA_AMP_MUTE, 0);
cdcd9268 506 } else {
47fd830a
TI
507 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
508 HDA_AMP_MUTE, HDA_AMP_MUTE);
509 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
510 HDA_AMP_MUTE, 0);
cdcd9268
JW
511 }
512 }
a9430dd8
JW
513 return change;
514}
515
4c5186ed 516#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 517 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
518 .info = alc_pin_mode_info, \
519 .get = alc_pin_mode_get, \
520 .put = alc_pin_mode_put, \
521 .private_value = nid | (dir<<16) }
df694daa 522
5c8f858d
JW
523/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
524 * together using a mask with more than one bit set. This control is
525 * currently used only by the ALC260 test model. At this stage they are not
526 * needed for any "production" models.
527 */
528#ifdef CONFIG_SND_DEBUG
a5ce8890 529#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 530
9c7f852e
TI
531static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
532 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
533{
534 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
535 hda_nid_t nid = kcontrol->private_value & 0xffff;
536 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
537 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
538 unsigned int val = snd_hda_codec_read(codec, nid, 0,
539 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
540
541 *valp = (val & mask) != 0;
542 return 0;
543}
9c7f852e
TI
544static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
546{
547 signed int change;
548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
549 hda_nid_t nid = kcontrol->private_value & 0xffff;
550 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
551 long val = *ucontrol->value.integer.value;
9c7f852e
TI
552 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
553 AC_VERB_GET_GPIO_DATA,
554 0x00);
5c8f858d
JW
555
556 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
557 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
558 if (val == 0)
5c8f858d
JW
559 gpio_data &= ~mask;
560 else
561 gpio_data |= mask;
82beb8fd
TI
562 snd_hda_codec_write_cache(codec, nid, 0,
563 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
564
565 return change;
566}
567#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
568 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
569 .info = alc_gpio_data_info, \
570 .get = alc_gpio_data_get, \
571 .put = alc_gpio_data_put, \
572 .private_value = nid | (mask<<16) }
573#endif /* CONFIG_SND_DEBUG */
574
92621f13
JW
575/* A switch control to allow the enabling of the digital IO pins on the
576 * ALC260. This is incredibly simplistic; the intention of this control is
577 * to provide something in the test model allowing digital outputs to be
578 * identified if present. If models are found which can utilise these
579 * outputs a more complete mixer control can be devised for those models if
580 * necessary.
581 */
582#ifdef CONFIG_SND_DEBUG
a5ce8890 583#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 584
9c7f852e
TI
585static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
586 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
587{
588 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
589 hda_nid_t nid = kcontrol->private_value & 0xffff;
590 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
591 long *valp = ucontrol->value.integer.value;
9c7f852e 592 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 593 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
594
595 *valp = (val & mask) != 0;
596 return 0;
597}
9c7f852e
TI
598static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
600{
601 signed int change;
602 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
603 hda_nid_t nid = kcontrol->private_value & 0xffff;
604 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
605 long val = *ucontrol->value.integer.value;
9c7f852e 606 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 607 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 608 0x00);
92621f13
JW
609
610 /* Set/unset the masked control bit(s) as needed */
9c7f852e 611 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
612 if (val==0)
613 ctrl_data &= ~mask;
614 else
615 ctrl_data |= mask;
82beb8fd
TI
616 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
617 ctrl_data);
92621f13
JW
618
619 return change;
620}
621#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
622 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
623 .info = alc_spdif_ctrl_info, \
624 .get = alc_spdif_ctrl_get, \
625 .put = alc_spdif_ctrl_put, \
626 .private_value = nid | (mask<<16) }
627#endif /* CONFIG_SND_DEBUG */
628
f8225f6d
JW
629/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
630 * Again, this is only used in the ALC26x test models to help identify when
631 * the EAPD line must be asserted for features to work.
632 */
633#ifdef CONFIG_SND_DEBUG
634#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
635
636static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
637 struct snd_ctl_elem_value *ucontrol)
638{
639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640 hda_nid_t nid = kcontrol->private_value & 0xffff;
641 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
642 long *valp = ucontrol->value.integer.value;
643 unsigned int val = snd_hda_codec_read(codec, nid, 0,
644 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
645
646 *valp = (val & mask) != 0;
647 return 0;
648}
649
650static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *ucontrol)
652{
653 int change;
654 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
655 hda_nid_t nid = kcontrol->private_value & 0xffff;
656 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
657 long val = *ucontrol->value.integer.value;
658 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
659 AC_VERB_GET_EAPD_BTLENABLE,
660 0x00);
661
662 /* Set/unset the masked control bit(s) as needed */
663 change = (!val ? 0 : mask) != (ctrl_data & mask);
664 if (!val)
665 ctrl_data &= ~mask;
666 else
667 ctrl_data |= mask;
668 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
669 ctrl_data);
670
671 return change;
672}
673
674#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
675 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
676 .info = alc_eapd_ctrl_info, \
677 .get = alc_eapd_ctrl_get, \
678 .put = alc_eapd_ctrl_put, \
679 .private_value = nid | (mask<<16) }
680#endif /* CONFIG_SND_DEBUG */
681
df694daa
KY
682/*
683 * set up from the preset table
684 */
9c7f852e
TI
685static void setup_preset(struct alc_spec *spec,
686 const struct alc_config_preset *preset)
df694daa
KY
687{
688 int i;
689
690 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
691 spec->mixers[spec->num_mixers++] = preset->mixers[i];
9c7f852e
TI
692 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
693 i++)
694 spec->init_verbs[spec->num_init_verbs++] =
695 preset->init_verbs[i];
df694daa
KY
696
697 spec->channel_mode = preset->channel_mode;
698 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 699 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
700
701 spec->multiout.max_channels = spec->channel_mode[0].channels;
702
703 spec->multiout.num_dacs = preset->num_dacs;
704 spec->multiout.dac_nids = preset->dac_nids;
705 spec->multiout.dig_out_nid = preset->dig_out_nid;
706 spec->multiout.hp_nid = preset->hp_nid;
707
a1e8d2da 708 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 709 if (!spec->num_mux_defs)
a1e8d2da 710 spec->num_mux_defs = 1;
df694daa
KY
711 spec->input_mux = preset->input_mux;
712
713 spec->num_adc_nids = preset->num_adc_nids;
714 spec->adc_nids = preset->adc_nids;
e1406348 715 spec->capsrc_nids = preset->capsrc_nids;
df694daa 716 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
717
718 spec->unsol_event = preset->unsol_event;
719 spec->init_hook = preset->init_hook;
cb53c626
TI
720#ifdef CONFIG_SND_HDA_POWER_SAVE
721 spec->loopback.amplist = preset->loopbacks;
722#endif
df694daa
KY
723}
724
bc9f98a9
KY
725/* Enable GPIO mask and set output */
726static struct hda_verb alc_gpio1_init_verbs[] = {
727 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
728 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
729 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
730 { }
731};
732
733static struct hda_verb alc_gpio2_init_verbs[] = {
734 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
735 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
736 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
737 { }
738};
739
bdd148a3
KY
740static struct hda_verb alc_gpio3_init_verbs[] = {
741 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
742 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
743 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
744 { }
745};
746
c9b58006
KY
747static void alc_sku_automute(struct hda_codec *codec)
748{
749 struct alc_spec *spec = codec->spec;
c9b58006
KY
750 unsigned int present;
751 unsigned int hp_nid = spec->autocfg.hp_pins[0];
752 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
753
754 /* need to execute and sync at first */
755 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
756 present = snd_hda_codec_read(codec, hp_nid, 0,
757 AC_VERB_GET_PIN_SENSE, 0);
758 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
759 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
760 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
761}
762
763/* unsolicited event for HP jack sensing */
764static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
765{
766 if (codec->vendor_id == 0x10ec0880)
767 res >>= 28;
768 else
769 res >>= 26;
770 if (res != ALC880_HP_EVENT)
771 return;
772
773 alc_sku_automute(codec);
774}
775
bc9f98a9
KY
776/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
777 * 31 ~ 16 : Manufacture ID
778 * 15 ~ 8 : SKU ID
779 * 7 ~ 0 : Assembly ID
780 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
781 */
782static void alc_subsystem_id(struct hda_codec *codec,
783 unsigned int porta, unsigned int porte,
784 unsigned int portd)
785{
c9b58006
KY
786 unsigned int ass, tmp, i;
787 unsigned nid;
788 struct alc_spec *spec = codec->spec;
bc9f98a9 789
c9b58006
KY
790 ass = codec->subsystem_id & 0xffff;
791 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
792 goto do_sku;
793
794 /*
795 * 31~30 : port conetcivity
796 * 29~21 : reserve
797 * 20 : PCBEEP input
798 * 19~16 : Check sum (15:1)
799 * 15~1 : Custom
800 * 0 : override
801 */
802 nid = 0x1d;
803 if (codec->vendor_id == 0x10ec0260)
804 nid = 0x17;
805 ass = snd_hda_codec_read(codec, nid, 0,
806 AC_VERB_GET_CONFIG_DEFAULT, 0);
807 if (!(ass & 1) && !(ass & 0x100000))
808 return;
809 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
810 return;
811
c9b58006
KY
812 /* check sum */
813 tmp = 0;
814 for (i = 1; i < 16; i++) {
8c427226 815 if ((ass >> i) & 1)
c9b58006
KY
816 tmp++;
817 }
818 if (((ass >> 16) & 0xf) != tmp)
819 return;
820do_sku:
821 /*
822 * 0 : override
823 * 1 : Swap Jack
824 * 2 : 0 --> Desktop, 1 --> Laptop
825 * 3~5 : External Amplifier control
826 * 7~6 : Reserved
827 */
bc9f98a9
KY
828 tmp = (ass & 0x38) >> 3; /* external Amp control */
829 switch (tmp) {
830 case 1:
831 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
832 break;
833 case 3:
834 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
835 break;
bdd148a3
KY
836 case 7:
837 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
838 break;
c9b58006 839 case 5: /* set EAPD output high */
bdd148a3 840 switch (codec->vendor_id) {
c9b58006
KY
841 case 0x10ec0260:
842 snd_hda_codec_write(codec, 0x0f, 0,
843 AC_VERB_SET_EAPD_BTLENABLE, 2);
844 snd_hda_codec_write(codec, 0x10, 0,
845 AC_VERB_SET_EAPD_BTLENABLE, 2);
846 break;
847 case 0x10ec0262:
bdd148a3
KY
848 case 0x10ec0267:
849 case 0x10ec0268:
c9b58006
KY
850 case 0x10ec0269:
851 case 0x10ec0862:
852 case 0x10ec0662:
bdd148a3
KY
853 snd_hda_codec_write(codec, 0x14, 0,
854 AC_VERB_SET_EAPD_BTLENABLE, 2);
855 snd_hda_codec_write(codec, 0x15, 0,
856 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 857 break;
bdd148a3 858 }
c9b58006
KY
859 switch (codec->vendor_id) {
860 case 0x10ec0260:
861 snd_hda_codec_write(codec, 0x1a, 0,
862 AC_VERB_SET_COEF_INDEX, 7);
863 tmp = snd_hda_codec_read(codec, 0x1a, 0,
864 AC_VERB_GET_PROC_COEF, 0);
865 snd_hda_codec_write(codec, 0x1a, 0,
866 AC_VERB_SET_COEF_INDEX, 7);
867 snd_hda_codec_write(codec, 0x1a, 0,
868 AC_VERB_SET_PROC_COEF,
869 tmp | 0x2010);
870 break;
871 case 0x10ec0262:
872 case 0x10ec0880:
873 case 0x10ec0882:
874 case 0x10ec0883:
875 case 0x10ec0885:
876 case 0x10ec0888:
877 snd_hda_codec_write(codec, 0x20, 0,
878 AC_VERB_SET_COEF_INDEX, 7);
879 tmp = snd_hda_codec_read(codec, 0x20, 0,
880 AC_VERB_GET_PROC_COEF, 0);
881 snd_hda_codec_write(codec, 0x20, 0,
882 AC_VERB_SET_COEF_INDEX, 7);
883 snd_hda_codec_write(codec, 0x20, 0,
884 AC_VERB_SET_PROC_COEF,
885 tmp | 0x2010);
886 break;
887 case 0x10ec0267:
888 case 0x10ec0268:
889 snd_hda_codec_write(codec, 0x20, 0,
890 AC_VERB_SET_COEF_INDEX, 7);
891 tmp = snd_hda_codec_read(codec, 0x20, 0,
892 AC_VERB_GET_PROC_COEF, 0);
893 snd_hda_codec_write(codec, 0x20, 0,
894 AC_VERB_SET_COEF_INDEX, 7);
895 snd_hda_codec_write(codec, 0x20, 0,
896 AC_VERB_SET_PROC_COEF,
897 tmp | 0x3000);
898 break;
bc9f98a9 899 }
c9b58006 900 default:
bc9f98a9
KY
901 break;
902 }
c9b58006 903
8c427226 904 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
905 * when the external headphone out jack is plugged"
906 */
8c427226 907 if (!(ass & 0x8000))
c9b58006
KY
908 return;
909 /*
910 * 10~8 : Jack location
911 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
912 * 14~13: Resvered
913 * 15 : 1 --> enable the function "Mute internal speaker
914 * when the external headphone out jack is plugged"
915 */
916 if (!spec->autocfg.speaker_pins[0]) {
8c427226 917 if (spec->autocfg.line_out_pins[0])
c9b58006 918 spec->autocfg.speaker_pins[0] =
8c427226 919 spec->autocfg.line_out_pins[0];
c9b58006
KY
920 else
921 return;
922 }
923
924 if (!spec->autocfg.hp_pins[0]) {
925 tmp = (ass >> 11) & 0x3; /* HP to chassis */
926 if (tmp == 0)
927 spec->autocfg.hp_pins[0] = porta;
928 else if (tmp == 1)
929 spec->autocfg.hp_pins[0] = porte;
930 else if (tmp == 2)
931 spec->autocfg.hp_pins[0] = portd;
932 else
933 return;
934 }
935
936 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
937 AC_VERB_SET_UNSOLICITED_ENABLE,
938 AC_USRSP_EN | ALC880_HP_EVENT);
939 spec->unsol_event = alc_sku_unsol_event;
940 spec->init_hook = alc_sku_automute;
bc9f98a9
KY
941}
942
f95474ec
TI
943/*
944 * Fix-up pin default configurations
945 */
946
947struct alc_pincfg {
948 hda_nid_t nid;
949 u32 val;
950};
951
952static void alc_fix_pincfg(struct hda_codec *codec,
953 const struct snd_pci_quirk *quirk,
954 const struct alc_pincfg **pinfix)
955{
956 const struct alc_pincfg *cfg;
957
958 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
959 if (!quirk)
960 return;
961
962 cfg = pinfix[quirk->value];
963 for (; cfg->nid; cfg++) {
964 int i;
965 u32 val = cfg->val;
966 for (i = 0; i < 4; i++) {
967 snd_hda_codec_write(codec, cfg->nid, 0,
968 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
969 val & 0xff);
970 val >>= 8;
971 }
972 }
973}
974
1da177e4 975/*
e9edcee0
TI
976 * ALC880 3-stack model
977 *
978 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
979 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
980 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
981 */
982
e9edcee0
TI
983static hda_nid_t alc880_dac_nids[4] = {
984 /* front, rear, clfe, rear_surr */
985 0x02, 0x05, 0x04, 0x03
986};
987
988static hda_nid_t alc880_adc_nids[3] = {
989 /* ADC0-2 */
990 0x07, 0x08, 0x09,
991};
992
993/* The datasheet says the node 0x07 is connected from inputs,
994 * but it shows zero connection in the real implementation on some devices.
df694daa 995 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 996 */
e9edcee0
TI
997static hda_nid_t alc880_adc_nids_alt[2] = {
998 /* ADC1-2 */
999 0x08, 0x09,
1000};
1001
1002#define ALC880_DIGOUT_NID 0x06
1003#define ALC880_DIGIN_NID 0x0a
1004
1005static struct hda_input_mux alc880_capture_source = {
1006 .num_items = 4,
1007 .items = {
1008 { "Mic", 0x0 },
1009 { "Front Mic", 0x3 },
1010 { "Line", 0x2 },
1011 { "CD", 0x4 },
1012 },
1013};
1014
1015/* channel source setting (2/6 channel selection for 3-stack) */
1016/* 2ch mode */
1017static struct hda_verb alc880_threestack_ch2_init[] = {
1018 /* set line-in to input, mute it */
1019 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1020 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1021 /* set mic-in to input vref 80%, mute it */
1022 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1023 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1024 { } /* end */
1025};
1026
1027/* 6ch mode */
1028static struct hda_verb alc880_threestack_ch6_init[] = {
1029 /* set line-in to output, unmute it */
1030 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1031 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1032 /* set mic-in to output, unmute it */
1033 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1034 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1035 { } /* end */
1036};
1037
d2a6d7dc 1038static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1039 { 2, alc880_threestack_ch2_init },
1040 { 6, alc880_threestack_ch6_init },
1041};
1042
c8b6bf9b 1043static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1044 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1045 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1046 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1047 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1048 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1049 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1050 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1051 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1052 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1053 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1054 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1055 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1057 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1058 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1059 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1060 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1061 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1062 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1063 {
1064 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1065 .name = "Channel Mode",
df694daa
KY
1066 .info = alc_ch_mode_info,
1067 .get = alc_ch_mode_get,
1068 .put = alc_ch_mode_put,
e9edcee0
TI
1069 },
1070 { } /* end */
1071};
1072
1073/* capture mixer elements */
c8b6bf9b 1074static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1075 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1076 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1077 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1078 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1079 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1080 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1081 {
1082 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1083 /* The multiple "Capture Source" controls confuse alsamixer
1084 * So call somewhat different..
1da177e4
LT
1085 */
1086 /* .name = "Capture Source", */
1087 .name = "Input Source",
e9edcee0 1088 .count = 3,
1da177e4
LT
1089 .info = alc_mux_enum_info,
1090 .get = alc_mux_enum_get,
1091 .put = alc_mux_enum_put,
1092 },
1da177e4
LT
1093 { } /* end */
1094};
1095
e9edcee0 1096/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1097static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1098 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1099 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1100 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1101 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1102 {
1103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1104 /* The multiple "Capture Source" controls confuse alsamixer
1105 * So call somewhat different..
1da177e4
LT
1106 */
1107 /* .name = "Capture Source", */
1108 .name = "Input Source",
1109 .count = 2,
1110 .info = alc_mux_enum_info,
1111 .get = alc_mux_enum_get,
1112 .put = alc_mux_enum_put,
1113 },
1da177e4
LT
1114 { } /* end */
1115};
1116
e9edcee0
TI
1117
1118
1119/*
1120 * ALC880 5-stack model
1121 *
9c7f852e
TI
1122 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1123 * Side = 0x02 (0xd)
e9edcee0
TI
1124 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1125 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1126 */
1127
1128/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1129static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1130 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1131 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1132 { } /* end */
1133};
1134
e9edcee0
TI
1135/* channel source setting (6/8 channel selection for 5-stack) */
1136/* 6ch mode */
1137static struct hda_verb alc880_fivestack_ch6_init[] = {
1138 /* set line-in to input, mute it */
1139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1141 { } /* end */
1142};
1143
e9edcee0
TI
1144/* 8ch mode */
1145static struct hda_verb alc880_fivestack_ch8_init[] = {
1146 /* set line-in to output, unmute it */
1147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1149 { } /* end */
1150};
1151
d2a6d7dc 1152static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1153 { 6, alc880_fivestack_ch6_init },
1154 { 8, alc880_fivestack_ch8_init },
1155};
1156
1157
1158/*
1159 * ALC880 6-stack model
1160 *
9c7f852e
TI
1161 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1162 * Side = 0x05 (0x0f)
e9edcee0
TI
1163 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1164 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1165 */
1166
1167static hda_nid_t alc880_6st_dac_nids[4] = {
1168 /* front, rear, clfe, rear_surr */
1169 0x02, 0x03, 0x04, 0x05
f12ab1e0 1170};
e9edcee0
TI
1171
1172static struct hda_input_mux alc880_6stack_capture_source = {
1173 .num_items = 4,
1174 .items = {
1175 { "Mic", 0x0 },
1176 { "Front Mic", 0x1 },
1177 { "Line", 0x2 },
1178 { "CD", 0x4 },
1179 },
1180};
1181
1182/* fixed 8-channels */
d2a6d7dc 1183static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1184 { 8, NULL },
1185};
1186
c8b6bf9b 1187static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1188 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1189 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1190 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1191 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1192 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1193 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1194 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1195 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1196 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1197 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1198 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1199 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1200 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1201 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1205 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1206 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1207 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1208 {
1209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1210 .name = "Channel Mode",
df694daa
KY
1211 .info = alc_ch_mode_info,
1212 .get = alc_ch_mode_get,
1213 .put = alc_ch_mode_put,
16ded525
TI
1214 },
1215 { } /* end */
1216};
1217
e9edcee0
TI
1218
1219/*
1220 * ALC880 W810 model
1221 *
1222 * W810 has rear IO for:
1223 * Front (DAC 02)
1224 * Surround (DAC 03)
1225 * Center/LFE (DAC 04)
1226 * Digital out (06)
1227 *
1228 * The system also has a pair of internal speakers, and a headphone jack.
1229 * These are both connected to Line2 on the codec, hence to DAC 02.
1230 *
1231 * There is a variable resistor to control the speaker or headphone
1232 * volume. This is a hardware-only device without a software API.
1233 *
1234 * Plugging headphones in will disable the internal speakers. This is
1235 * implemented in hardware, not via the driver using jack sense. In
1236 * a similar fashion, plugging into the rear socket marked "front" will
1237 * disable both the speakers and headphones.
1238 *
1239 * For input, there's a microphone jack, and an "audio in" jack.
1240 * These may not do anything useful with this driver yet, because I
1241 * haven't setup any initialization verbs for these yet...
1242 */
1243
1244static hda_nid_t alc880_w810_dac_nids[3] = {
1245 /* front, rear/surround, clfe */
1246 0x02, 0x03, 0x04
16ded525
TI
1247};
1248
e9edcee0 1249/* fixed 6 channels */
d2a6d7dc 1250static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1251 { 6, NULL }
1252};
1253
1254/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1255static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1256 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1257 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1258 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1259 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1260 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1261 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1262 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1263 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1264 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1265 { } /* end */
1266};
1267
1268
1269/*
1270 * Z710V model
1271 *
1272 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1273 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1274 * Line = 0x1a
e9edcee0
TI
1275 */
1276
1277static hda_nid_t alc880_z71v_dac_nids[1] = {
1278 0x02
1279};
1280#define ALC880_Z71V_HP_DAC 0x03
1281
1282/* fixed 2 channels */
d2a6d7dc 1283static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1284 { 2, NULL }
1285};
1286
c8b6bf9b 1287static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1289 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1291 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1292 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1293 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1296 { } /* end */
1297};
1298
e9edcee0 1299
e9edcee0
TI
1300/*
1301 * ALC880 F1734 model
1302 *
1303 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1304 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1305 */
1306
1307static hda_nid_t alc880_f1734_dac_nids[1] = {
1308 0x03
1309};
1310#define ALC880_F1734_HP_DAC 0x02
1311
c8b6bf9b 1312static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1313 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1314 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1315 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1316 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1317 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1318 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1321 { } /* end */
1322};
1323
937b4160
TI
1324static struct hda_input_mux alc880_f1734_capture_source = {
1325 .num_items = 2,
1326 .items = {
1327 { "Mic", 0x1 },
1328 { "CD", 0x4 },
1329 },
1330};
1331
e9edcee0 1332
e9edcee0
TI
1333/*
1334 * ALC880 ASUS model
1335 *
1336 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1337 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1338 * Mic = 0x18, Line = 0x1a
1339 */
1340
1341#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1342#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1343
c8b6bf9b 1344static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1347 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1348 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1349 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1350 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1351 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1352 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1353 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1354 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1355 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1356 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1357 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1358 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1359 {
1360 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1361 .name = "Channel Mode",
df694daa
KY
1362 .info = alc_ch_mode_info,
1363 .get = alc_ch_mode_get,
1364 .put = alc_ch_mode_put,
16ded525
TI
1365 },
1366 { } /* end */
1367};
e9edcee0 1368
e9edcee0
TI
1369/*
1370 * ALC880 ASUS W1V model
1371 *
1372 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1373 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1374 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1375 */
1376
1377/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1378static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1379 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1380 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1381 { } /* end */
1382};
1383
3c10a9d9 1384/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1385static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1386 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1387 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1388 { } /* end */
1389};
e9edcee0 1390
df694daa
KY
1391/* TCL S700 */
1392static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1393 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1394 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1396 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1397 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1399 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1400 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1401 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1402 {
1403 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1404 /* The multiple "Capture Source" controls confuse alsamixer
1405 * So call somewhat different..
df694daa
KY
1406 */
1407 /* .name = "Capture Source", */
1408 .name = "Input Source",
1409 .count = 1,
1410 .info = alc_mux_enum_info,
1411 .get = alc_mux_enum_get,
1412 .put = alc_mux_enum_put,
1413 },
1414 { } /* end */
1415};
1416
ccc656ce
KY
1417/* Uniwill */
1418static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1419 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1420 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1421 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1422 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1423 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1424 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1425 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1426 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1427 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1428 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1433 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1434 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1435 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1436 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1437 {
1438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1439 .name = "Channel Mode",
1440 .info = alc_ch_mode_info,
1441 .get = alc_ch_mode_get,
1442 .put = alc_ch_mode_put,
1443 },
1444 { } /* end */
1445};
1446
2cf9f0fc
TD
1447static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1448 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1449 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1450 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1451 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1452 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1453 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1454 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1455 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1456 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1457 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1458 { } /* end */
1459};
1460
ccc656ce 1461static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1462 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1463 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1464 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1465 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1468 { } /* end */
1469};
1470
2134ea4f
TI
1471/*
1472 * virtual master controls
1473 */
1474
1475/*
1476 * slave controls for virtual master
1477 */
1478static const char *alc_slave_vols[] = {
1479 "Front Playback Volume",
1480 "Surround Playback Volume",
1481 "Center Playback Volume",
1482 "LFE Playback Volume",
1483 "Side Playback Volume",
1484 "Headphone Playback Volume",
1485 "Speaker Playback Volume",
1486 "Mono Playback Volume",
2134ea4f
TI
1487 "Line-Out Playback Volume",
1488 NULL,
1489};
1490
1491static const char *alc_slave_sws[] = {
1492 "Front Playback Switch",
1493 "Surround Playback Switch",
1494 "Center Playback Switch",
1495 "LFE Playback Switch",
1496 "Side Playback Switch",
1497 "Headphone Playback Switch",
1498 "Speaker Playback Switch",
1499 "Mono Playback Switch",
edb54a55 1500 "IEC958 Playback Switch",
2134ea4f
TI
1501 NULL,
1502};
1503
1da177e4 1504/*
e9edcee0 1505 * build control elements
1da177e4
LT
1506 */
1507static int alc_build_controls(struct hda_codec *codec)
1508{
1509 struct alc_spec *spec = codec->spec;
1510 int err;
1511 int i;
1512
1513 for (i = 0; i < spec->num_mixers; i++) {
1514 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1515 if (err < 0)
1516 return err;
1517 }
1518
1519 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1520 err = snd_hda_create_spdif_out_ctls(codec,
1521 spec->multiout.dig_out_nid);
1da177e4
LT
1522 if (err < 0)
1523 return err;
9a08160b
TI
1524 err = snd_hda_create_spdif_share_sw(codec,
1525 &spec->multiout);
1526 if (err < 0)
1527 return err;
1528 spec->multiout.share_spdif = 1;
1da177e4
LT
1529 }
1530 if (spec->dig_in_nid) {
1531 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1532 if (err < 0)
1533 return err;
1534 }
2134ea4f
TI
1535
1536 /* if we have no master control, let's create it */
1537 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 1538 unsigned int vmaster_tlv[4];
2134ea4f 1539 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 1540 HDA_OUTPUT, vmaster_tlv);
2134ea4f 1541 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 1542 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
1543 if (err < 0)
1544 return err;
1545 }
1546 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1547 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1548 NULL, alc_slave_sws);
1549 if (err < 0)
1550 return err;
1551 }
1552
1da177e4
LT
1553 return 0;
1554}
1555
e9edcee0 1556
1da177e4
LT
1557/*
1558 * initialize the codec volumes, etc
1559 */
1560
e9edcee0
TI
1561/*
1562 * generic initialization of ADC, input mixers and output mixers
1563 */
1564static struct hda_verb alc880_volume_init_verbs[] = {
1565 /*
1566 * Unmute ADC0-2 and set the default input to mic-in
1567 */
71fe7b82 1568 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1570 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1571 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1572 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1574
e9edcee0
TI
1575 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1576 * mixer widget
9c7f852e
TI
1577 * Note: PASD motherboards uses the Line In 2 as the input for front
1578 * panel mic (mic 2)
1da177e4 1579 */
e9edcee0 1580 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1584 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1588
e9edcee0
TI
1589 /*
1590 * Set up output mixers (0x0c - 0x0f)
1da177e4 1591 */
e9edcee0
TI
1592 /* set vol=0 to output mixers */
1593 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1595 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1597 /* set up input amps for analog loopback */
1598 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1601 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1602 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1604 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1605 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1606 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1607
1608 { }
1609};
1610
e9edcee0
TI
1611/*
1612 * 3-stack pin configuration:
1613 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1614 */
1615static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1616 /*
1617 * preset connection lists of input pins
1618 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1619 */
1620 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1621 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1622 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1623
1624 /*
1625 * Set pin mode and muting
1626 */
1627 /* set front pin widgets 0x14 for output */
05acb863 1628 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1629 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1630 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1633 /* Mic2 (as headphone out) for HP output */
1634 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1636 /* Line In pin widget for input */
05acb863 1637 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1639 /* Line2 (as front mic) pin widget for input and vref at 80% */
1640 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1641 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1642 /* CD pin widget for input */
05acb863 1643 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1644
e9edcee0
TI
1645 { }
1646};
1da177e4 1647
e9edcee0
TI
1648/*
1649 * 5-stack pin configuration:
1650 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1651 * line-in/side = 0x1a, f-mic = 0x1b
1652 */
1653static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1654 /*
1655 * preset connection lists of input pins
1656 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1657 */
e9edcee0
TI
1658 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1659 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1660
e9edcee0
TI
1661 /*
1662 * Set pin mode and muting
1da177e4 1663 */
e9edcee0
TI
1664 /* set pin widgets 0x14-0x17 for output */
1665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1666 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1667 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1669 /* unmute pins for output (no gain on this amp) */
1670 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1672 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1673 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1674
1675 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1678 /* Mic2 (as headphone out) for HP output */
1679 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1680 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681 /* Line In pin widget for input */
1682 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1683 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1684 /* Line2 (as front mic) pin widget for input and vref at 80% */
1685 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1686 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1687 /* CD pin widget for input */
1688 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1689
1690 { }
1691};
1692
e9edcee0
TI
1693/*
1694 * W810 pin configuration:
1695 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1696 */
1697static struct hda_verb alc880_pin_w810_init_verbs[] = {
1698 /* hphone/speaker input selector: front DAC */
1699 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1700
05acb863 1701 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1702 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1704 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1705 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1706 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1707
e9edcee0 1708 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1709 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1710
1da177e4
LT
1711 { }
1712};
1713
e9edcee0
TI
1714/*
1715 * Z71V pin configuration:
1716 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1717 */
1718static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1719 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1720 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1721 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1722 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1723
16ded525 1724 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1725 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1727 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1728
1729 { }
1730};
1731
e9edcee0
TI
1732/*
1733 * 6-stack pin configuration:
9c7f852e
TI
1734 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1735 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1736 */
1737static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1738 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1739
16ded525 1740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1743 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1745 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1746 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1748
16ded525 1749 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1751 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1752 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1753 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1757 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1758
e9edcee0
TI
1759 { }
1760};
1761
ccc656ce
KY
1762/*
1763 * Uniwill pin configuration:
1764 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1765 * line = 0x1a
1766 */
1767static struct hda_verb alc880_uniwill_init_verbs[] = {
1768 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1769
1770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1772 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1773 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1774 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1775 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1776 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1777 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1779 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1780 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1781 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1782 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1783 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1784
1785 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1786 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1787 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1789 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1790 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1791 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1792 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1793 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1794
1795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1797
1798 { }
1799};
1800
1801/*
1802* Uniwill P53
1803* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1804 */
1805static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1806 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1807
1808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1813 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1817 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1818 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1819 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1820
1821 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1823 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1825 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1827
1828 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1829 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1830
1831 { }
1832};
1833
2cf9f0fc
TD
1834static struct hda_verb alc880_beep_init_verbs[] = {
1835 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1836 { }
1837};
1838
ccc656ce 1839/* toggle speaker-output according to the hp-jack state */
458a4fab 1840static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1841{
1842 unsigned int present;
f12ab1e0 1843 unsigned char bits;
ccc656ce
KY
1844
1845 present = snd_hda_codec_read(codec, 0x14, 0,
1846 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1847 bits = present ? HDA_AMP_MUTE : 0;
1848 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1849 HDA_AMP_MUTE, bits);
1850 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1851 HDA_AMP_MUTE, bits);
458a4fab
TI
1852}
1853
1854/* auto-toggle front mic */
1855static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1856{
1857 unsigned int present;
1858 unsigned char bits;
ccc656ce
KY
1859
1860 present = snd_hda_codec_read(codec, 0x18, 0,
1861 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1862 bits = present ? HDA_AMP_MUTE : 0;
1863 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1864}
1865
1866static void alc880_uniwill_automute(struct hda_codec *codec)
1867{
1868 alc880_uniwill_hp_automute(codec);
1869 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1870}
1871
1872static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1873 unsigned int res)
1874{
1875 /* Looks like the unsol event is incompatible with the standard
1876 * definition. 4bit tag is placed at 28 bit!
1877 */
458a4fab
TI
1878 switch (res >> 28) {
1879 case ALC880_HP_EVENT:
1880 alc880_uniwill_hp_automute(codec);
1881 break;
1882 case ALC880_MIC_EVENT:
1883 alc880_uniwill_mic_automute(codec);
1884 break;
1885 }
ccc656ce
KY
1886}
1887
1888static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1889{
1890 unsigned int present;
f12ab1e0 1891 unsigned char bits;
ccc656ce
KY
1892
1893 present = snd_hda_codec_read(codec, 0x14, 0,
1894 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1895 bits = present ? HDA_AMP_MUTE : 0;
1896 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1897}
1898
1899static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1900{
1901 unsigned int present;
1902
1903 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1904 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1905 present &= HDA_AMP_VOLMASK;
1906 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1907 HDA_AMP_VOLMASK, present);
1908 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1909 HDA_AMP_VOLMASK, present);
ccc656ce 1910}
47fd830a 1911
ccc656ce
KY
1912static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1913 unsigned int res)
1914{
1915 /* Looks like the unsol event is incompatible with the standard
1916 * definition. 4bit tag is placed at 28 bit!
1917 */
1918 if ((res >> 28) == ALC880_HP_EVENT)
1919 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1920 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1921 alc880_uniwill_p53_dcvol_automute(codec);
1922}
1923
e9edcee0
TI
1924/*
1925 * F1734 pin configuration:
1926 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1927 */
1928static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1929 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1930 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1931 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1932 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1933
e9edcee0 1934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1935 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1937 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1938
e9edcee0
TI
1939 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1940 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1941 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1942 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1943 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1944 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1945 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1946 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1947 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 1948
937b4160
TI
1949 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1950 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1951
dfc0ff62
TI
1952 { }
1953};
1954
e9edcee0
TI
1955/*
1956 * ASUS pin configuration:
1957 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1958 */
1959static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1960 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1961 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1962 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1963 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1964
1965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1969 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1971 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1972 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1973
1974 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1976 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1978 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1980 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1981 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1982 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1983
e9edcee0
TI
1984 { }
1985};
16ded525 1986
e9edcee0 1987/* Enable GPIO mask and set output */
bc9f98a9
KY
1988#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1989#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1990
1991/* Clevo m520g init */
1992static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1993 /* headphone output */
1994 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1995 /* line-out */
1996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1997 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1998 /* Line-in */
1999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2001 /* CD */
2002 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2003 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2004 /* Mic1 (rear panel) */
2005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007 /* Mic2 (front panel) */
2008 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2009 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2010 /* headphone */
2011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2013 /* change to EAPD mode */
2014 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2015 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2016
2017 { }
16ded525
TI
2018};
2019
df694daa 2020static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2021 /* change to EAPD mode */
2022 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2023 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2024
df694daa
KY
2025 /* Headphone output */
2026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2027 /* Front output*/
2028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2029 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2030
2031 /* Line In pin widget for input */
2032 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2033 /* CD pin widget for input */
2034 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2035 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2036 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2037
2038 /* change to EAPD mode */
2039 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2040 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2041
2042 { }
2043};
16ded525 2044
e9edcee0 2045/*
ae6b813a
TI
2046 * LG m1 express dual
2047 *
2048 * Pin assignment:
2049 * Rear Line-In/Out (blue): 0x14
2050 * Build-in Mic-In: 0x15
2051 * Speaker-out: 0x17
2052 * HP-Out (green): 0x1b
2053 * Mic-In/Out (red): 0x19
2054 * SPDIF-Out: 0x1e
2055 */
2056
2057/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2058static hda_nid_t alc880_lg_dac_nids[3] = {
2059 0x05, 0x02, 0x03
2060};
2061
2062/* seems analog CD is not working */
2063static struct hda_input_mux alc880_lg_capture_source = {
2064 .num_items = 3,
2065 .items = {
2066 { "Mic", 0x1 },
2067 { "Line", 0x5 },
2068 { "Internal Mic", 0x6 },
2069 },
2070};
2071
2072/* 2,4,6 channel modes */
2073static struct hda_verb alc880_lg_ch2_init[] = {
2074 /* set line-in and mic-in to input */
2075 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2076 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2077 { }
2078};
2079
2080static struct hda_verb alc880_lg_ch4_init[] = {
2081 /* set line-in to out and mic-in to input */
2082 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2083 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2084 { }
2085};
2086
2087static struct hda_verb alc880_lg_ch6_init[] = {
2088 /* set line-in and mic-in to output */
2089 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2090 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2091 { }
2092};
2093
2094static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2095 { 2, alc880_lg_ch2_init },
2096 { 4, alc880_lg_ch4_init },
2097 { 6, alc880_lg_ch6_init },
2098};
2099
2100static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2102 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2103 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2104 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2105 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2107 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2108 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2114 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2115 {
2116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2117 .name = "Channel Mode",
2118 .info = alc_ch_mode_info,
2119 .get = alc_ch_mode_get,
2120 .put = alc_ch_mode_put,
2121 },
2122 { } /* end */
2123};
2124
2125static struct hda_verb alc880_lg_init_verbs[] = {
2126 /* set capture source to mic-in */
2127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2128 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2129 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2130 /* mute all amp mixer inputs */
2131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2132 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2133 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2134 /* line-in to input */
2135 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2136 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2137 /* built-in mic */
2138 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2139 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2140 /* speaker-out */
2141 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2142 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2143 /* mic-in to input */
2144 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2145 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2146 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2147 /* HP-out */
2148 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2150 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2151 /* jack sense */
2152 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2153 { }
2154};
2155
2156/* toggle speaker-output according to the hp-jack state */
2157static void alc880_lg_automute(struct hda_codec *codec)
2158{
2159 unsigned int present;
f12ab1e0 2160 unsigned char bits;
ae6b813a
TI
2161
2162 present = snd_hda_codec_read(codec, 0x1b, 0,
2163 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2164 bits = present ? HDA_AMP_MUTE : 0;
2165 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2166 HDA_AMP_MUTE, bits);
ae6b813a
TI
2167}
2168
2169static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2170{
2171 /* Looks like the unsol event is incompatible with the standard
2172 * definition. 4bit tag is placed at 28 bit!
2173 */
2174 if ((res >> 28) == 0x01)
2175 alc880_lg_automute(codec);
2176}
2177
d681518a
TI
2178/*
2179 * LG LW20
2180 *
2181 * Pin assignment:
2182 * Speaker-out: 0x14
2183 * Mic-In: 0x18
e4f41da9
CM
2184 * Built-in Mic-In: 0x19
2185 * Line-In: 0x1b
2186 * HP-Out: 0x1a
d681518a
TI
2187 * SPDIF-Out: 0x1e
2188 */
2189
d681518a 2190static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2191 .num_items = 3,
d681518a
TI
2192 .items = {
2193 { "Mic", 0x0 },
2194 { "Internal Mic", 0x1 },
e4f41da9 2195 { "Line In", 0x2 },
d681518a
TI
2196 },
2197};
2198
0a8c5da3
CM
2199#define alc880_lg_lw_modes alc880_threestack_modes
2200
d681518a 2201static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2204 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2205 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2206 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2207 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2208 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2209 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2210 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2211 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2215 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2216 {
2217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2218 .name = "Channel Mode",
2219 .info = alc_ch_mode_info,
2220 .get = alc_ch_mode_get,
2221 .put = alc_ch_mode_put,
2222 },
d681518a
TI
2223 { } /* end */
2224};
2225
2226static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2227 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2228 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2229 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2230
d681518a
TI
2231 /* set capture source to mic-in */
2232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2234 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2235 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2236 /* speaker-out */
2237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2239 /* HP-out */
d681518a
TI
2240 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2241 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2242 /* mic-in to input */
2243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2245 /* built-in mic */
2246 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2247 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2248 /* jack sense */
2249 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2250 { }
2251};
2252
2253/* toggle speaker-output according to the hp-jack state */
2254static void alc880_lg_lw_automute(struct hda_codec *codec)
2255{
2256 unsigned int present;
f12ab1e0 2257 unsigned char bits;
d681518a
TI
2258
2259 present = snd_hda_codec_read(codec, 0x1b, 0,
2260 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2261 bits = present ? HDA_AMP_MUTE : 0;
2262 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2263 HDA_AMP_MUTE, bits);
d681518a
TI
2264}
2265
2266static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2267{
2268 /* Looks like the unsol event is incompatible with the standard
2269 * definition. 4bit tag is placed at 28 bit!
2270 */
2271 if ((res >> 28) == 0x01)
2272 alc880_lg_lw_automute(codec);
2273}
2274
cb53c626
TI
2275#ifdef CONFIG_SND_HDA_POWER_SAVE
2276static struct hda_amp_list alc880_loopbacks[] = {
2277 { 0x0b, HDA_INPUT, 0 },
2278 { 0x0b, HDA_INPUT, 1 },
2279 { 0x0b, HDA_INPUT, 2 },
2280 { 0x0b, HDA_INPUT, 3 },
2281 { 0x0b, HDA_INPUT, 4 },
2282 { } /* end */
2283};
2284
2285static struct hda_amp_list alc880_lg_loopbacks[] = {
2286 { 0x0b, HDA_INPUT, 1 },
2287 { 0x0b, HDA_INPUT, 6 },
2288 { 0x0b, HDA_INPUT, 7 },
2289 { } /* end */
2290};
2291#endif
2292
ae6b813a
TI
2293/*
2294 * Common callbacks
e9edcee0
TI
2295 */
2296
1da177e4
LT
2297static int alc_init(struct hda_codec *codec)
2298{
2299 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2300 unsigned int i;
2301
2302 for (i = 0; i < spec->num_init_verbs; i++)
2303 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2304
2305 if (spec->init_hook)
2306 spec->init_hook(codec);
2307
1da177e4
LT
2308 return 0;
2309}
2310
ae6b813a
TI
2311static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2312{
2313 struct alc_spec *spec = codec->spec;
2314
2315 if (spec->unsol_event)
2316 spec->unsol_event(codec, res);
2317}
2318
cb53c626
TI
2319#ifdef CONFIG_SND_HDA_POWER_SAVE
2320static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2321{
2322 struct alc_spec *spec = codec->spec;
2323 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2324}
2325#endif
2326
1da177e4
LT
2327/*
2328 * Analog playback callbacks
2329 */
2330static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2331 struct hda_codec *codec,
c8b6bf9b 2332 struct snd_pcm_substream *substream)
1da177e4
LT
2333{
2334 struct alc_spec *spec = codec->spec;
9a08160b
TI
2335 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2336 hinfo);
1da177e4
LT
2337}
2338
2339static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2340 struct hda_codec *codec,
2341 unsigned int stream_tag,
2342 unsigned int format,
c8b6bf9b 2343 struct snd_pcm_substream *substream)
1da177e4
LT
2344{
2345 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2346 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2347 stream_tag, format, substream);
1da177e4
LT
2348}
2349
2350static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2351 struct hda_codec *codec,
c8b6bf9b 2352 struct snd_pcm_substream *substream)
1da177e4
LT
2353{
2354 struct alc_spec *spec = codec->spec;
2355 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2356}
2357
2358/*
2359 * Digital out
2360 */
2361static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2362 struct hda_codec *codec,
c8b6bf9b 2363 struct snd_pcm_substream *substream)
1da177e4
LT
2364{
2365 struct alc_spec *spec = codec->spec;
2366 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2367}
2368
6b97eb45
TI
2369static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2370 struct hda_codec *codec,
2371 unsigned int stream_tag,
2372 unsigned int format,
2373 struct snd_pcm_substream *substream)
2374{
2375 struct alc_spec *spec = codec->spec;
2376 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2377 stream_tag, format, substream);
2378}
2379
1da177e4
LT
2380static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2381 struct hda_codec *codec,
c8b6bf9b 2382 struct snd_pcm_substream *substream)
1da177e4
LT
2383{
2384 struct alc_spec *spec = codec->spec;
2385 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2386}
2387
2388/*
2389 * Analog capture
2390 */
6330079f 2391static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2392 struct hda_codec *codec,
2393 unsigned int stream_tag,
2394 unsigned int format,
c8b6bf9b 2395 struct snd_pcm_substream *substream)
1da177e4
LT
2396{
2397 struct alc_spec *spec = codec->spec;
2398
6330079f 2399 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2400 stream_tag, 0, format);
2401 return 0;
2402}
2403
6330079f 2404static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2405 struct hda_codec *codec,
c8b6bf9b 2406 struct snd_pcm_substream *substream)
1da177e4
LT
2407{
2408 struct alc_spec *spec = codec->spec;
2409
6330079f 2410 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
9c7f852e 2411 0, 0, 0);
1da177e4
LT
2412 return 0;
2413}
2414
2415
2416/*
2417 */
2418static struct hda_pcm_stream alc880_pcm_analog_playback = {
2419 .substreams = 1,
2420 .channels_min = 2,
2421 .channels_max = 8,
e9edcee0 2422 /* NID is set in alc_build_pcms */
1da177e4
LT
2423 .ops = {
2424 .open = alc880_playback_pcm_open,
2425 .prepare = alc880_playback_pcm_prepare,
2426 .cleanup = alc880_playback_pcm_cleanup
2427 },
2428};
2429
2430static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2431 .substreams = 1,
2432 .channels_min = 2,
2433 .channels_max = 2,
2434 /* NID is set in alc_build_pcms */
2435};
2436
2437static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2438 .substreams = 1,
2439 .channels_min = 2,
2440 .channels_max = 2,
2441 /* NID is set in alc_build_pcms */
2442};
2443
2444static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2445 .substreams = 2, /* can be overridden */
1da177e4
LT
2446 .channels_min = 2,
2447 .channels_max = 2,
e9edcee0 2448 /* NID is set in alc_build_pcms */
1da177e4 2449 .ops = {
6330079f
TI
2450 .prepare = alc880_alt_capture_pcm_prepare,
2451 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2452 },
2453};
2454
2455static struct hda_pcm_stream alc880_pcm_digital_playback = {
2456 .substreams = 1,
2457 .channels_min = 2,
2458 .channels_max = 2,
2459 /* NID is set in alc_build_pcms */
2460 .ops = {
2461 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2462 .close = alc880_dig_playback_pcm_close,
2463 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2464 },
2465};
2466
2467static struct hda_pcm_stream alc880_pcm_digital_capture = {
2468 .substreams = 1,
2469 .channels_min = 2,
2470 .channels_max = 2,
2471 /* NID is set in alc_build_pcms */
2472};
2473
4c5186ed 2474/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2475static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2476 .substreams = 0,
2477 .channels_min = 0,
2478 .channels_max = 0,
2479};
2480
1da177e4
LT
2481static int alc_build_pcms(struct hda_codec *codec)
2482{
2483 struct alc_spec *spec = codec->spec;
2484 struct hda_pcm *info = spec->pcm_rec;
2485 int i;
2486
2487 codec->num_pcms = 1;
2488 codec->pcm_info = info;
2489
2490 info->name = spec->stream_name_analog;
4a471b7d
TI
2491 if (spec->stream_analog_playback) {
2492 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2493 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2494 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2495 }
2496 if (spec->stream_analog_capture) {
2497 snd_assert(spec->adc_nids, return -EINVAL);
2498 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2499 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2500 }
2501
2502 if (spec->channel_mode) {
2503 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2504 for (i = 0; i < spec->num_channel_mode; i++) {
2505 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2506 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2507 }
1da177e4
LT
2508 }
2509 }
2510
e08a007d 2511 /* SPDIF for stream index #1 */
1da177e4 2512 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2513 codec->num_pcms = 2;
c06134d7 2514 info = spec->pcm_rec + 1;
1da177e4 2515 info->name = spec->stream_name_digital;
7ba72ba1 2516 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2517 if (spec->multiout.dig_out_nid &&
2518 spec->stream_digital_playback) {
1da177e4
LT
2519 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2520 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2521 }
4a471b7d
TI
2522 if (spec->dig_in_nid &&
2523 spec->stream_digital_capture) {
1da177e4
LT
2524 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2525 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2526 }
2527 }
2528
e08a007d
TI
2529 /* If the use of more than one ADC is requested for the current
2530 * model, configure a second analog capture-only PCM.
2531 */
2532 /* Additional Analaog capture for index #2 */
6330079f
TI
2533 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2534 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2535 codec->num_pcms = 3;
c06134d7 2536 info = spec->pcm_rec + 2;
e08a007d 2537 info->name = spec->stream_name_analog;
6330079f
TI
2538 if (spec->alt_dac_nid) {
2539 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2540 *spec->stream_analog_alt_playback;
2541 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2542 spec->alt_dac_nid;
2543 } else {
2544 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2545 alc_pcm_null_stream;
2546 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2547 }
2548 if (spec->num_adc_nids > 1) {
2549 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2550 *spec->stream_analog_alt_capture;
2551 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2552 spec->adc_nids[1];
2553 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2554 spec->num_adc_nids - 1;
2555 } else {
2556 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2557 alc_pcm_null_stream;
2558 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2559 }
2560 }
2561
1da177e4
LT
2562 return 0;
2563}
2564
2565static void alc_free(struct hda_codec *codec)
2566{
e9edcee0
TI
2567 struct alc_spec *spec = codec->spec;
2568 unsigned int i;
2569
f12ab1e0 2570 if (!spec)
e9edcee0
TI
2571 return;
2572
2573 if (spec->kctl_alloc) {
2574 for (i = 0; i < spec->num_kctl_used; i++)
2575 kfree(spec->kctl_alloc[i].name);
2576 kfree(spec->kctl_alloc);
2577 }
2578 kfree(spec);
1da177e4
LT
2579}
2580
2581/*
2582 */
2583static struct hda_codec_ops alc_patch_ops = {
2584 .build_controls = alc_build_controls,
2585 .build_pcms = alc_build_pcms,
2586 .init = alc_init,
2587 .free = alc_free,
ae6b813a 2588 .unsol_event = alc_unsol_event,
cb53c626
TI
2589#ifdef CONFIG_SND_HDA_POWER_SAVE
2590 .check_power_status = alc_check_power_status,
2591#endif
1da177e4
LT
2592};
2593
2fa522be
TI
2594
2595/*
2596 * Test configuration for debugging
2597 *
2598 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2599 * enum controls.
2600 */
2601#ifdef CONFIG_SND_DEBUG
2602static hda_nid_t alc880_test_dac_nids[4] = {
2603 0x02, 0x03, 0x04, 0x05
2604};
2605
2606static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2607 .num_items = 7,
2fa522be
TI
2608 .items = {
2609 { "In-1", 0x0 },
2610 { "In-2", 0x1 },
2611 { "In-3", 0x2 },
2612 { "In-4", 0x3 },
2613 { "CD", 0x4 },
ae6b813a
TI
2614 { "Front", 0x5 },
2615 { "Surround", 0x6 },
2fa522be
TI
2616 },
2617};
2618
d2a6d7dc 2619static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2620 { 2, NULL },
fd2c326d 2621 { 4, NULL },
2fa522be 2622 { 6, NULL },
fd2c326d 2623 { 8, NULL },
2fa522be
TI
2624};
2625
9c7f852e
TI
2626static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2627 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2628{
2629 static char *texts[] = {
2630 "N/A", "Line Out", "HP Out",
2631 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2632 };
2633 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2634 uinfo->count = 1;
2635 uinfo->value.enumerated.items = 8;
2636 if (uinfo->value.enumerated.item >= 8)
2637 uinfo->value.enumerated.item = 7;
2638 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2639 return 0;
2640}
2641
9c7f852e
TI
2642static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2643 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2644{
2645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2646 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2647 unsigned int pin_ctl, item = 0;
2648
2649 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2650 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2651 if (pin_ctl & AC_PINCTL_OUT_EN) {
2652 if (pin_ctl & AC_PINCTL_HP_EN)
2653 item = 2;
2654 else
2655 item = 1;
2656 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2657 switch (pin_ctl & AC_PINCTL_VREFEN) {
2658 case AC_PINCTL_VREF_HIZ: item = 3; break;
2659 case AC_PINCTL_VREF_50: item = 4; break;
2660 case AC_PINCTL_VREF_GRD: item = 5; break;
2661 case AC_PINCTL_VREF_80: item = 6; break;
2662 case AC_PINCTL_VREF_100: item = 7; break;
2663 }
2664 }
2665 ucontrol->value.enumerated.item[0] = item;
2666 return 0;
2667}
2668
9c7f852e
TI
2669static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2670 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2671{
2672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2673 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2674 static unsigned int ctls[] = {
2675 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2676 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2677 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2678 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2679 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2680 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2681 };
2682 unsigned int old_ctl, new_ctl;
2683
2684 old_ctl = snd_hda_codec_read(codec, nid, 0,
2685 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2686 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2687 if (old_ctl != new_ctl) {
82beb8fd
TI
2688 int val;
2689 snd_hda_codec_write_cache(codec, nid, 0,
2690 AC_VERB_SET_PIN_WIDGET_CONTROL,
2691 new_ctl);
47fd830a
TI
2692 val = ucontrol->value.enumerated.item[0] >= 3 ?
2693 HDA_AMP_MUTE : 0;
2694 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2695 HDA_AMP_MUTE, val);
2fa522be
TI
2696 return 1;
2697 }
2698 return 0;
2699}
2700
9c7f852e
TI
2701static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2702 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2703{
2704 static char *texts[] = {
2705 "Front", "Surround", "CLFE", "Side"
2706 };
2707 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2708 uinfo->count = 1;
2709 uinfo->value.enumerated.items = 4;
2710 if (uinfo->value.enumerated.item >= 4)
2711 uinfo->value.enumerated.item = 3;
2712 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2713 return 0;
2714}
2715
9c7f852e
TI
2716static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2717 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2718{
2719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2720 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2721 unsigned int sel;
2722
2723 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2724 ucontrol->value.enumerated.item[0] = sel & 3;
2725 return 0;
2726}
2727
9c7f852e
TI
2728static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2729 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2730{
2731 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2732 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2733 unsigned int sel;
2734
2735 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2736 if (ucontrol->value.enumerated.item[0] != sel) {
2737 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2738 snd_hda_codec_write_cache(codec, nid, 0,
2739 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2740 return 1;
2741 }
2742 return 0;
2743}
2744
2745#define PIN_CTL_TEST(xname,nid) { \
2746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2747 .name = xname, \
2748 .info = alc_test_pin_ctl_info, \
2749 .get = alc_test_pin_ctl_get, \
2750 .put = alc_test_pin_ctl_put, \
2751 .private_value = nid \
2752 }
2753
2754#define PIN_SRC_TEST(xname,nid) { \
2755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2756 .name = xname, \
2757 .info = alc_test_pin_src_info, \
2758 .get = alc_test_pin_src_get, \
2759 .put = alc_test_pin_src_put, \
2760 .private_value = nid \
2761 }
2762
c8b6bf9b 2763static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2764 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2765 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2766 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2767 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2768 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2769 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2770 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2771 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2772 PIN_CTL_TEST("Front Pin Mode", 0x14),
2773 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2774 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2775 PIN_CTL_TEST("Side Pin Mode", 0x17),
2776 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2777 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2778 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2779 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2780 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2781 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2782 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2783 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2784 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2785 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2786 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2787 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2788 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2789 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2790 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2791 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2794 {
2795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2796 .name = "Channel Mode",
df694daa
KY
2797 .info = alc_ch_mode_info,
2798 .get = alc_ch_mode_get,
2799 .put = alc_ch_mode_put,
2fa522be
TI
2800 },
2801 { } /* end */
2802};
2803
2804static struct hda_verb alc880_test_init_verbs[] = {
2805 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2810 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2811 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2813 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2814 /* Vol output for 0x0c-0x0f */
05acb863
TI
2815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2817 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2818 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2819 /* Set output pins 0x14-0x17 */
05acb863
TI
2820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2821 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2822 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2823 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2824 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2829 /* Set input pins 0x18-0x1c */
16ded525
TI
2830 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2832 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2833 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2834 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2835 /* Mute input pins 0x18-0x1b */
05acb863
TI
2836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2840 /* ADC set up */
05acb863 2841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2842 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2843 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2844 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2845 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2846 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2847 /* Analog input/passthru */
2848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2853 { }
2854};
2855#endif
2856
1da177e4
LT
2857/*
2858 */
2859
f5fcc13c
TI
2860static const char *alc880_models[ALC880_MODEL_LAST] = {
2861 [ALC880_3ST] = "3stack",
2862 [ALC880_TCL_S700] = "tcl",
2863 [ALC880_3ST_DIG] = "3stack-digout",
2864 [ALC880_CLEVO] = "clevo",
2865 [ALC880_5ST] = "5stack",
2866 [ALC880_5ST_DIG] = "5stack-digout",
2867 [ALC880_W810] = "w810",
2868 [ALC880_Z71V] = "z71v",
2869 [ALC880_6ST] = "6stack",
2870 [ALC880_6ST_DIG] = "6stack-digout",
2871 [ALC880_ASUS] = "asus",
2872 [ALC880_ASUS_W1V] = "asus-w1v",
2873 [ALC880_ASUS_DIG] = "asus-dig",
2874 [ALC880_ASUS_DIG2] = "asus-dig2",
2875 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2876 [ALC880_UNIWILL_P53] = "uniwill-p53",
2877 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2878 [ALC880_F1734] = "F1734",
2879 [ALC880_LG] = "lg",
2880 [ALC880_LG_LW] = "lg-lw",
2fa522be 2881#ifdef CONFIG_SND_DEBUG
f5fcc13c 2882 [ALC880_TEST] = "test",
2fa522be 2883#endif
f5fcc13c
TI
2884 [ALC880_AUTO] = "auto",
2885};
2886
2887static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2888 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2889 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2890 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2891 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2892 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2893 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2894 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2895 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2896 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2897 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2898 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2899 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2900 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2901 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2902 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2903 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2904 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2905 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2906 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2907 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2908 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
0e4ceb75 2909 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
f5fcc13c
TI
2910 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2911 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2912 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2913 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2914 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2915 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2916 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2917 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2918 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2919 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2920 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2921 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2922 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
2923 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2924 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 2925 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 2926 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 2927 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 2928 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
2929 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2930 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741
TI
2931 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2932 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 2933 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 2934 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 2935 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 2936 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 2937 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
2938 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2939 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 2940 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
2941 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2942 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2943 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2944 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
2945 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2946 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 2947 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 2948 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2949 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2950 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
2951 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2952 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2953 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2954 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2955 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2956 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
2957 {}
2958};
2959
16ded525 2960/*
df694daa 2961 * ALC880 codec presets
16ded525 2962 */
16ded525
TI
2963static struct alc_config_preset alc880_presets[] = {
2964 [ALC880_3ST] = {
e9edcee0 2965 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2966 .init_verbs = { alc880_volume_init_verbs,
2967 alc880_pin_3stack_init_verbs },
16ded525 2968 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 2969 .dac_nids = alc880_dac_nids,
16ded525
TI
2970 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2971 .channel_mode = alc880_threestack_modes,
4e195a7b 2972 .need_dac_fix = 1,
16ded525
TI
2973 .input_mux = &alc880_capture_source,
2974 },
2975 [ALC880_3ST_DIG] = {
e9edcee0 2976 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2977 .init_verbs = { alc880_volume_init_verbs,
2978 alc880_pin_3stack_init_verbs },
16ded525 2979 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
2980 .dac_nids = alc880_dac_nids,
2981 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2982 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2983 .channel_mode = alc880_threestack_modes,
4e195a7b 2984 .need_dac_fix = 1,
16ded525
TI
2985 .input_mux = &alc880_capture_source,
2986 },
df694daa
KY
2987 [ALC880_TCL_S700] = {
2988 .mixers = { alc880_tcl_s700_mixer },
2989 .init_verbs = { alc880_volume_init_verbs,
2990 alc880_pin_tcl_S700_init_verbs,
2991 alc880_gpio2_init_verbs },
2992 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2993 .dac_nids = alc880_dac_nids,
2994 .hp_nid = 0x03,
2995 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2996 .channel_mode = alc880_2_jack_modes,
2997 .input_mux = &alc880_capture_source,
2998 },
16ded525 2999 [ALC880_5ST] = {
f12ab1e0
TI
3000 .mixers = { alc880_three_stack_mixer,
3001 alc880_five_stack_mixer},
3002 .init_verbs = { alc880_volume_init_verbs,
3003 alc880_pin_5stack_init_verbs },
16ded525
TI
3004 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3005 .dac_nids = alc880_dac_nids,
16ded525
TI
3006 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3007 .channel_mode = alc880_fivestack_modes,
3008 .input_mux = &alc880_capture_source,
3009 },
3010 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3011 .mixers = { alc880_three_stack_mixer,
3012 alc880_five_stack_mixer },
3013 .init_verbs = { alc880_volume_init_verbs,
3014 alc880_pin_5stack_init_verbs },
16ded525
TI
3015 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3016 .dac_nids = alc880_dac_nids,
3017 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3018 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3019 .channel_mode = alc880_fivestack_modes,
3020 .input_mux = &alc880_capture_source,
3021 },
b6482d48
TI
3022 [ALC880_6ST] = {
3023 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3024 .init_verbs = { alc880_volume_init_verbs,
3025 alc880_pin_6stack_init_verbs },
b6482d48
TI
3026 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3027 .dac_nids = alc880_6st_dac_nids,
3028 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3029 .channel_mode = alc880_sixstack_modes,
3030 .input_mux = &alc880_6stack_capture_source,
3031 },
16ded525 3032 [ALC880_6ST_DIG] = {
e9edcee0 3033 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3034 .init_verbs = { alc880_volume_init_verbs,
3035 alc880_pin_6stack_init_verbs },
16ded525
TI
3036 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3037 .dac_nids = alc880_6st_dac_nids,
3038 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3039 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3040 .channel_mode = alc880_sixstack_modes,
3041 .input_mux = &alc880_6stack_capture_source,
3042 },
3043 [ALC880_W810] = {
e9edcee0 3044 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3045 .init_verbs = { alc880_volume_init_verbs,
3046 alc880_pin_w810_init_verbs,
b0af0de5 3047 alc880_gpio2_init_verbs },
16ded525
TI
3048 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3049 .dac_nids = alc880_w810_dac_nids,
3050 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3051 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3052 .channel_mode = alc880_w810_modes,
3053 .input_mux = &alc880_capture_source,
3054 },
3055 [ALC880_Z71V] = {
e9edcee0 3056 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3057 .init_verbs = { alc880_volume_init_verbs,
3058 alc880_pin_z71v_init_verbs },
16ded525
TI
3059 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3060 .dac_nids = alc880_z71v_dac_nids,
3061 .dig_out_nid = ALC880_DIGOUT_NID,
3062 .hp_nid = 0x03,
e9edcee0
TI
3063 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3064 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3065 .input_mux = &alc880_capture_source,
3066 },
3067 [ALC880_F1734] = {
e9edcee0 3068 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3069 .init_verbs = { alc880_volume_init_verbs,
3070 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3071 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3072 .dac_nids = alc880_f1734_dac_nids,
3073 .hp_nid = 0x02,
3074 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3075 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3076 .input_mux = &alc880_f1734_capture_source,
3077 .unsol_event = alc880_uniwill_p53_unsol_event,
3078 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3079 },
3080 [ALC880_ASUS] = {
e9edcee0 3081 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3082 .init_verbs = { alc880_volume_init_verbs,
3083 alc880_pin_asus_init_verbs,
e9edcee0
TI
3084 alc880_gpio1_init_verbs },
3085 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3086 .dac_nids = alc880_asus_dac_nids,
3087 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3088 .channel_mode = alc880_asus_modes,
4e195a7b 3089 .need_dac_fix = 1,
16ded525
TI
3090 .input_mux = &alc880_capture_source,
3091 },
3092 [ALC880_ASUS_DIG] = {
e9edcee0 3093 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3094 .init_verbs = { alc880_volume_init_verbs,
3095 alc880_pin_asus_init_verbs,
e9edcee0
TI
3096 alc880_gpio1_init_verbs },
3097 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3098 .dac_nids = alc880_asus_dac_nids,
16ded525 3099 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3100 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3101 .channel_mode = alc880_asus_modes,
4e195a7b 3102 .need_dac_fix = 1,
16ded525
TI
3103 .input_mux = &alc880_capture_source,
3104 },
df694daa
KY
3105 [ALC880_ASUS_DIG2] = {
3106 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3107 .init_verbs = { alc880_volume_init_verbs,
3108 alc880_pin_asus_init_verbs,
df694daa
KY
3109 alc880_gpio2_init_verbs }, /* use GPIO2 */
3110 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3111 .dac_nids = alc880_asus_dac_nids,
3112 .dig_out_nid = ALC880_DIGOUT_NID,
3113 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3114 .channel_mode = alc880_asus_modes,
4e195a7b 3115 .need_dac_fix = 1,
df694daa
KY
3116 .input_mux = &alc880_capture_source,
3117 },
16ded525 3118 [ALC880_ASUS_W1V] = {
e9edcee0 3119 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3120 .init_verbs = { alc880_volume_init_verbs,
3121 alc880_pin_asus_init_verbs,
e9edcee0
TI
3122 alc880_gpio1_init_verbs },
3123 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3124 .dac_nids = alc880_asus_dac_nids,
16ded525 3125 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3126 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3127 .channel_mode = alc880_asus_modes,
4e195a7b 3128 .need_dac_fix = 1,
16ded525
TI
3129 .input_mux = &alc880_capture_source,
3130 },
3131 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3132 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3133 .init_verbs = { alc880_volume_init_verbs,
3134 alc880_pin_asus_init_verbs },
e9edcee0
TI
3135 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3136 .dac_nids = alc880_asus_dac_nids,
16ded525 3137 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3138 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3139 .channel_mode = alc880_asus_modes,
4e195a7b 3140 .need_dac_fix = 1,
16ded525
TI
3141 .input_mux = &alc880_capture_source,
3142 },
ccc656ce
KY
3143 [ALC880_UNIWILL] = {
3144 .mixers = { alc880_uniwill_mixer },
3145 .init_verbs = { alc880_volume_init_verbs,
3146 alc880_uniwill_init_verbs },
3147 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3148 .dac_nids = alc880_asus_dac_nids,
3149 .dig_out_nid = ALC880_DIGOUT_NID,
3150 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3151 .channel_mode = alc880_threestack_modes,
3152 .need_dac_fix = 1,
3153 .input_mux = &alc880_capture_source,
3154 .unsol_event = alc880_uniwill_unsol_event,
3155 .init_hook = alc880_uniwill_automute,
3156 },
3157 [ALC880_UNIWILL_P53] = {
3158 .mixers = { alc880_uniwill_p53_mixer },
3159 .init_verbs = { alc880_volume_init_verbs,
3160 alc880_uniwill_p53_init_verbs },
3161 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3162 .dac_nids = alc880_asus_dac_nids,
3163 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3164 .channel_mode = alc880_threestack_modes,
3165 .input_mux = &alc880_capture_source,
3166 .unsol_event = alc880_uniwill_p53_unsol_event,
3167 .init_hook = alc880_uniwill_p53_hp_automute,
3168 },
3169 [ALC880_FUJITSU] = {
f12ab1e0 3170 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3171 alc880_pcbeep_mixer, },
3172 .init_verbs = { alc880_volume_init_verbs,
3173 alc880_uniwill_p53_init_verbs,
3174 alc880_beep_init_verbs },
3175 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3176 .dac_nids = alc880_dac_nids,
d53d7d9e 3177 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3178 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3179 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3180 .input_mux = &alc880_capture_source,
3181 .unsol_event = alc880_uniwill_p53_unsol_event,
3182 .init_hook = alc880_uniwill_p53_hp_automute,
3183 },
df694daa
KY
3184 [ALC880_CLEVO] = {
3185 .mixers = { alc880_three_stack_mixer },
3186 .init_verbs = { alc880_volume_init_verbs,
3187 alc880_pin_clevo_init_verbs },
3188 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3189 .dac_nids = alc880_dac_nids,
3190 .hp_nid = 0x03,
3191 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3192 .channel_mode = alc880_threestack_modes,
4e195a7b 3193 .need_dac_fix = 1,
df694daa
KY
3194 .input_mux = &alc880_capture_source,
3195 },
ae6b813a
TI
3196 [ALC880_LG] = {
3197 .mixers = { alc880_lg_mixer },
3198 .init_verbs = { alc880_volume_init_verbs,
3199 alc880_lg_init_verbs },
3200 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3201 .dac_nids = alc880_lg_dac_nids,
3202 .dig_out_nid = ALC880_DIGOUT_NID,
3203 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3204 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3205 .need_dac_fix = 1,
ae6b813a
TI
3206 .input_mux = &alc880_lg_capture_source,
3207 .unsol_event = alc880_lg_unsol_event,
3208 .init_hook = alc880_lg_automute,
cb53c626
TI
3209#ifdef CONFIG_SND_HDA_POWER_SAVE
3210 .loopbacks = alc880_lg_loopbacks,
3211#endif
ae6b813a 3212 },
d681518a
TI
3213 [ALC880_LG_LW] = {
3214 .mixers = { alc880_lg_lw_mixer },
3215 .init_verbs = { alc880_volume_init_verbs,
3216 alc880_lg_lw_init_verbs },
0a8c5da3 3217 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3218 .dac_nids = alc880_dac_nids,
3219 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3220 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3221 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3222 .input_mux = &alc880_lg_lw_capture_source,
3223 .unsol_event = alc880_lg_lw_unsol_event,
3224 .init_hook = alc880_lg_lw_automute,
3225 },
16ded525
TI
3226#ifdef CONFIG_SND_DEBUG
3227 [ALC880_TEST] = {
e9edcee0
TI
3228 .mixers = { alc880_test_mixer },
3229 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3230 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3231 .dac_nids = alc880_test_dac_nids,
3232 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3233 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3234 .channel_mode = alc880_test_modes,
3235 .input_mux = &alc880_test_capture_source,
3236 },
3237#endif
3238};
3239
e9edcee0
TI
3240/*
3241 * Automatic parse of I/O pins from the BIOS configuration
3242 */
3243
3244#define NUM_CONTROL_ALLOC 32
3245#define NUM_VERB_ALLOC 32
3246
3247enum {
3248 ALC_CTL_WIDGET_VOL,
3249 ALC_CTL_WIDGET_MUTE,
3250 ALC_CTL_BIND_MUTE,
3251};
c8b6bf9b 3252static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3253 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3254 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3255 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3256};
3257
3258/* add dynamic controls */
f12ab1e0
TI
3259static int add_control(struct alc_spec *spec, int type, const char *name,
3260 unsigned long val)
e9edcee0 3261{
c8b6bf9b 3262 struct snd_kcontrol_new *knew;
e9edcee0
TI
3263
3264 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3265 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3266
f12ab1e0
TI
3267 /* array + terminator */
3268 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3269 if (!knew)
e9edcee0
TI
3270 return -ENOMEM;
3271 if (spec->kctl_alloc) {
f12ab1e0
TI
3272 memcpy(knew, spec->kctl_alloc,
3273 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3274 kfree(spec->kctl_alloc);
3275 }
3276 spec->kctl_alloc = knew;
3277 spec->num_kctl_alloc = num;
3278 }
3279
3280 knew = &spec->kctl_alloc[spec->num_kctl_used];
3281 *knew = alc880_control_templates[type];
543537bd 3282 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3283 if (!knew->name)
e9edcee0
TI
3284 return -ENOMEM;
3285 knew->private_value = val;
3286 spec->num_kctl_used++;
3287 return 0;
3288}
3289
3290#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3291#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3292#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3293#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3294#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3295#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3296#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3297#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3298#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3299#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3300#define ALC880_PIN_CD_NID 0x1c
3301
3302/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3303static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3304 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3305{
3306 hda_nid_t nid;
3307 int assigned[4];
3308 int i, j;
3309
3310 memset(assigned, 0, sizeof(assigned));
b0af0de5 3311 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3312
3313 /* check the pins hardwired to audio widget */
3314 for (i = 0; i < cfg->line_outs; i++) {
3315 nid = cfg->line_out_pins[i];
3316 if (alc880_is_fixed_pin(nid)) {
3317 int idx = alc880_fixed_pin_idx(nid);
5014f193 3318 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3319 assigned[idx] = 1;
3320 }
3321 }
3322 /* left pins can be connect to any audio widget */
3323 for (i = 0; i < cfg->line_outs; i++) {
3324 nid = cfg->line_out_pins[i];
3325 if (alc880_is_fixed_pin(nid))
3326 continue;
3327 /* search for an empty channel */
3328 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3329 if (!assigned[j]) {
3330 spec->multiout.dac_nids[i] =
3331 alc880_idx_to_dac(j);
e9edcee0
TI
3332 assigned[j] = 1;
3333 break;
3334 }
3335 }
3336 }
3337 spec->multiout.num_dacs = cfg->line_outs;
3338 return 0;
3339}
3340
3341/* add playback controls from the parsed DAC table */
df694daa
KY
3342static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3343 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3344{
3345 char name[32];
f12ab1e0
TI
3346 static const char *chname[4] = {
3347 "Front", "Surround", NULL /*CLFE*/, "Side"
3348 };
e9edcee0
TI
3349 hda_nid_t nid;
3350 int i, err;
3351
3352 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3353 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3354 continue;
3355 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3356 if (i == 2) {
3357 /* Center/LFE */
f12ab1e0
TI
3358 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3359 "Center Playback Volume",
3360 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3361 HDA_OUTPUT));
3362 if (err < 0)
e9edcee0 3363 return err;
f12ab1e0
TI
3364 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3365 "LFE Playback Volume",
3366 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3367 HDA_OUTPUT));
3368 if (err < 0)
e9edcee0 3369 return err;
f12ab1e0
TI
3370 err = add_control(spec, ALC_CTL_BIND_MUTE,
3371 "Center Playback Switch",
3372 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3373 HDA_INPUT));
3374 if (err < 0)
e9edcee0 3375 return err;
f12ab1e0
TI
3376 err = add_control(spec, ALC_CTL_BIND_MUTE,
3377 "LFE Playback Switch",
3378 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3379 HDA_INPUT));
3380 if (err < 0)
e9edcee0
TI
3381 return err;
3382 } else {
3383 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3384 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3385 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3386 HDA_OUTPUT));
3387 if (err < 0)
e9edcee0
TI
3388 return err;
3389 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3390 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3391 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3392 HDA_INPUT));
3393 if (err < 0)
e9edcee0
TI
3394 return err;
3395 }
3396 }
e9edcee0
TI
3397 return 0;
3398}
3399
8d88bc3d
TI
3400/* add playback controls for speaker and HP outputs */
3401static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3402 const char *pfx)
e9edcee0
TI
3403{
3404 hda_nid_t nid;
3405 int err;
8d88bc3d 3406 char name[32];
e9edcee0 3407
f12ab1e0 3408 if (!pin)
e9edcee0
TI
3409 return 0;
3410
3411 if (alc880_is_fixed_pin(pin)) {
3412 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3413 /* specify the DAC as the extra output */
f12ab1e0 3414 if (!spec->multiout.hp_nid)
e9edcee0 3415 spec->multiout.hp_nid = nid;
82bc955f
TI
3416 else
3417 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3418 /* control HP volume/switch on the output mixer amp */
3419 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3420 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3421 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3422 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3423 if (err < 0)
e9edcee0 3424 return err;
8d88bc3d 3425 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3426 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3427 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3428 if (err < 0)
e9edcee0
TI
3429 return err;
3430 } else if (alc880_is_multi_pin(pin)) {
3431 /* set manual connection */
e9edcee0 3432 /* we have only a switch on HP-out PIN */
8d88bc3d 3433 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3434 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3435 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3436 if (err < 0)
e9edcee0
TI
3437 return err;
3438 }
3439 return 0;
3440}
3441
3442/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3443static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3444 const char *ctlname,
df694daa 3445 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3446{
3447 char name[32];
df694daa 3448 int err;
e9edcee0
TI
3449
3450 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3451 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3452 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3453 if (err < 0)
e9edcee0
TI
3454 return err;
3455 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3456 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3457 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3458 if (err < 0)
e9edcee0
TI
3459 return err;
3460 return 0;
3461}
3462
3463/* create playback/capture controls for input pins */
df694daa
KY
3464static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3465 const struct auto_pin_cfg *cfg)
e9edcee0 3466{
e9edcee0 3467 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3468 int i, err, idx;
e9edcee0
TI
3469
3470 for (i = 0; i < AUTO_PIN_LAST; i++) {
3471 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3472 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3473 err = new_analog_input(spec, cfg->input_pins[i],
3474 auto_pin_cfg_labels[i],
df694daa 3475 idx, 0x0b);
e9edcee0
TI
3476 if (err < 0)
3477 return err;
f12ab1e0
TI
3478 imux->items[imux->num_items].label =
3479 auto_pin_cfg_labels[i];
3480 imux->items[imux->num_items].index =
3481 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3482 imux->num_items++;
3483 }
3484 }
3485 return 0;
3486}
3487
f6c7e546
TI
3488static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3489 unsigned int pin_type)
3490{
3491 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3492 pin_type);
3493 /* unmute pin */
d260cdf6
TI
3494 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3495 AMP_OUT_UNMUTE);
f6c7e546
TI
3496}
3497
df694daa
KY
3498static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3499 hda_nid_t nid, int pin_type,
e9edcee0
TI
3500 int dac_idx)
3501{
f6c7e546 3502 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3503 /* need the manual connection? */
3504 if (alc880_is_multi_pin(nid)) {
3505 struct alc_spec *spec = codec->spec;
3506 int idx = alc880_multi_pin_idx(nid);
3507 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3508 AC_VERB_SET_CONNECT_SEL,
3509 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3510 }
3511}
3512
baba8ee9
TI
3513static int get_pin_type(int line_out_type)
3514{
3515 if (line_out_type == AUTO_PIN_HP_OUT)
3516 return PIN_HP;
3517 else
3518 return PIN_OUT;
3519}
3520
e9edcee0
TI
3521static void alc880_auto_init_multi_out(struct hda_codec *codec)
3522{
3523 struct alc_spec *spec = codec->spec;
3524 int i;
bc9f98a9
KY
3525
3526 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3527 for (i = 0; i < spec->autocfg.line_outs; i++) {
3528 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3529 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3530 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3531 }
3532}
3533
8d88bc3d 3534static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3535{
3536 struct alc_spec *spec = codec->spec;
3537 hda_nid_t pin;
3538
82bc955f 3539 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3540 if (pin) /* connect to front */
3541 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3542 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3543 if (pin) /* connect to front */
3544 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3545}
3546
3547static void alc880_auto_init_analog_input(struct hda_codec *codec)
3548{
3549 struct alc_spec *spec = codec->spec;
3550 int i;
3551
3552 for (i = 0; i < AUTO_PIN_LAST; i++) {
3553 hda_nid_t nid = spec->autocfg.input_pins[i];
3554 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3555 snd_hda_codec_write(codec, nid, 0,
3556 AC_VERB_SET_PIN_WIDGET_CONTROL,
3557 i <= AUTO_PIN_FRONT_MIC ?
3558 PIN_VREF80 : PIN_IN);
e9edcee0 3559 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3560 snd_hda_codec_write(codec, nid, 0,
3561 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3562 AMP_OUT_MUTE);
3563 }
3564 }
3565}
3566
3567/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3568/* return 1 if successful, 0 if the proper config is not found,
3569 * or a negative error code
3570 */
e9edcee0
TI
3571static int alc880_parse_auto_config(struct hda_codec *codec)
3572{
3573 struct alc_spec *spec = codec->spec;
3574 int err;
df694daa 3575 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3576
f12ab1e0
TI
3577 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3578 alc880_ignore);
3579 if (err < 0)
e9edcee0 3580 return err;
f12ab1e0 3581 if (!spec->autocfg.line_outs)
e9edcee0 3582 return 0; /* can't find valid BIOS pin config */
df694daa 3583
f12ab1e0
TI
3584 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3585 if (err < 0)
3586 return err;
3587 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3588 if (err < 0)
3589 return err;
3590 err = alc880_auto_create_extra_out(spec,
3591 spec->autocfg.speaker_pins[0],
3592 "Speaker");
3593 if (err < 0)
3594 return err;
3595 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3596 "Headphone");
3597 if (err < 0)
3598 return err;
3599 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3600 if (err < 0)
e9edcee0
TI
3601 return err;
3602
3603 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3604
3605 if (spec->autocfg.dig_out_pin)
3606 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3607 if (spec->autocfg.dig_in_pin)
3608 spec->dig_in_nid = ALC880_DIGIN_NID;
3609
3610 if (spec->kctl_alloc)
3611 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3612
3613 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3614
a1e8d2da 3615 spec->num_mux_defs = 1;
e9edcee0
TI
3616 spec->input_mux = &spec->private_imux;
3617
3618 return 1;
3619}
3620
ae6b813a
TI
3621/* additional initialization for auto-configuration model */
3622static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3623{
f6c7e546 3624 struct alc_spec *spec = codec->spec;
e9edcee0 3625 alc880_auto_init_multi_out(codec);
8d88bc3d 3626 alc880_auto_init_extra_out(codec);
e9edcee0 3627 alc880_auto_init_analog_input(codec);
f6c7e546
TI
3628 if (spec->unsol_event)
3629 alc_sku_automute(codec);
e9edcee0
TI
3630}
3631
3632/*
3633 * OK, here we have finally the patch for ALC880
3634 */
3635
1da177e4
LT
3636static int patch_alc880(struct hda_codec *codec)
3637{
3638 struct alc_spec *spec;
3639 int board_config;
df694daa 3640 int err;
1da177e4 3641
e560d8d8 3642 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3643 if (spec == NULL)
3644 return -ENOMEM;
3645
3646 codec->spec = spec;
3647
f5fcc13c
TI
3648 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3649 alc880_models,
3650 alc880_cfg_tbl);
3651 if (board_config < 0) {
9c7f852e
TI
3652 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3653 "trying auto-probe from BIOS...\n");
e9edcee0 3654 board_config = ALC880_AUTO;
1da177e4 3655 }
1da177e4 3656
e9edcee0
TI
3657 if (board_config == ALC880_AUTO) {
3658 /* automatic parse from the BIOS config */
3659 err = alc880_parse_auto_config(codec);
3660 if (err < 0) {
3661 alc_free(codec);
3662 return err;
f12ab1e0 3663 } else if (!err) {
9c7f852e
TI
3664 printk(KERN_INFO
3665 "hda_codec: Cannot set up configuration "
3666 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3667 board_config = ALC880_3ST;
3668 }
1da177e4
LT
3669 }
3670
df694daa
KY
3671 if (board_config != ALC880_AUTO)
3672 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3673
3674 spec->stream_name_analog = "ALC880 Analog";
3675 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3676 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3677 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3678
3679 spec->stream_name_digital = "ALC880 Digital";
3680 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3681 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3682
f12ab1e0 3683 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3684 /* check whether NID 0x07 is valid */
54d17403 3685 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3686 /* get type */
3687 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3688 if (wcap != AC_WID_AUD_IN) {
3689 spec->adc_nids = alc880_adc_nids_alt;
3690 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3691 spec->mixers[spec->num_mixers] =
3692 alc880_capture_alt_mixer;
e9edcee0
TI
3693 spec->num_mixers++;
3694 } else {
3695 spec->adc_nids = alc880_adc_nids;
3696 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3697 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3698 spec->num_mixers++;
3699 }
3700 }
1da177e4 3701
2134ea4f
TI
3702 spec->vmaster_nid = 0x0c;
3703
1da177e4 3704 codec->patch_ops = alc_patch_ops;
e9edcee0 3705 if (board_config == ALC880_AUTO)
ae6b813a 3706 spec->init_hook = alc880_auto_init;
cb53c626
TI
3707#ifdef CONFIG_SND_HDA_POWER_SAVE
3708 if (!spec->loopback.amplist)
3709 spec->loopback.amplist = alc880_loopbacks;
3710#endif
1da177e4
LT
3711
3712 return 0;
3713}
3714
e9edcee0 3715
1da177e4
LT
3716/*
3717 * ALC260 support
3718 */
3719
e9edcee0
TI
3720static hda_nid_t alc260_dac_nids[1] = {
3721 /* front */
3722 0x02,
3723};
3724
3725static hda_nid_t alc260_adc_nids[1] = {
3726 /* ADC0 */
3727 0x04,
3728};
3729
df694daa 3730static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3731 /* ADC1 */
3732 0x05,
3733};
3734
df694daa
KY
3735static hda_nid_t alc260_hp_adc_nids[2] = {
3736 /* ADC1, 0 */
3737 0x05, 0x04
3738};
3739
d57fdac0
JW
3740/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3741 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3742 */
3743static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3744 /* ADC0, ADC1 */
3745 0x04, 0x05
3746};
3747
e9edcee0
TI
3748#define ALC260_DIGOUT_NID 0x03
3749#define ALC260_DIGIN_NID 0x06
3750
3751static struct hda_input_mux alc260_capture_source = {
3752 .num_items = 4,
3753 .items = {
3754 { "Mic", 0x0 },
3755 { "Front Mic", 0x1 },
3756 { "Line", 0x2 },
3757 { "CD", 0x4 },
3758 },
3759};
3760
17e7aec6 3761/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3762 * headphone jack and the internal CD lines since these are the only pins at
3763 * which audio can appear. For flexibility, also allow the option of
3764 * recording the mixer output on the second ADC (ADC0 doesn't have a
3765 * connection to the mixer output).
a9430dd8 3766 */
a1e8d2da
JW
3767static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3768 {
3769 .num_items = 3,
3770 .items = {
3771 { "Mic/Line", 0x0 },
3772 { "CD", 0x4 },
3773 { "Headphone", 0x2 },
3774 },
a9430dd8 3775 },
a1e8d2da
JW
3776 {
3777 .num_items = 4,
3778 .items = {
3779 { "Mic/Line", 0x0 },
3780 { "CD", 0x4 },
3781 { "Headphone", 0x2 },
3782 { "Mixer", 0x5 },
3783 },
3784 },
3785
a9430dd8
JW
3786};
3787
a1e8d2da
JW
3788/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3789 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3790 */
a1e8d2da
JW
3791static struct hda_input_mux alc260_acer_capture_sources[2] = {
3792 {
3793 .num_items = 4,
3794 .items = {
3795 { "Mic", 0x0 },
3796 { "Line", 0x2 },
3797 { "CD", 0x4 },
3798 { "Headphone", 0x5 },
3799 },
3800 },
3801 {
3802 .num_items = 5,
3803 .items = {
3804 { "Mic", 0x0 },
3805 { "Line", 0x2 },
3806 { "CD", 0x4 },
3807 { "Headphone", 0x6 },
3808 { "Mixer", 0x5 },
3809 },
0bfc90e9
JW
3810 },
3811};
1da177e4
LT
3812/*
3813 * This is just place-holder, so there's something for alc_build_pcms to look
3814 * at when it calculates the maximum number of channels. ALC260 has no mixer
3815 * element which allows changing the channel mode, so the verb list is
3816 * never used.
3817 */
d2a6d7dc 3818static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3819 { 2, NULL },
3820};
3821
df694daa
KY
3822
3823/* Mixer combinations
3824 *
3825 * basic: base_output + input + pc_beep + capture
3826 * HP: base_output + input + capture_alt
3827 * HP_3013: hp_3013 + input + capture
3828 * fujitsu: fujitsu + capture
0bfc90e9 3829 * acer: acer + capture
df694daa
KY
3830 */
3831
3832static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3833 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3834 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3835 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3836 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3837 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3838 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3839 { } /* end */
f12ab1e0 3840};
1da177e4 3841
df694daa 3842static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
3843 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3844 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3845 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3846 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3848 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3849 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3850 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3851 { } /* end */
3852};
3853
3854static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3855 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3856 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3857 { } /* end */
3858};
3859
bec15c3a
TI
3860/* update HP, line and mono out pins according to the master switch */
3861static void alc260_hp_master_update(struct hda_codec *codec,
3862 hda_nid_t hp, hda_nid_t line,
3863 hda_nid_t mono)
3864{
3865 struct alc_spec *spec = codec->spec;
3866 unsigned int val = spec->master_sw ? PIN_HP : 0;
3867 /* change HP and line-out pins */
3868 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3869 val);
3870 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3871 val);
3872 /* mono (speaker) depending on the HP jack sense */
3873 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3874 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3875 val);
3876}
3877
3878static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3879 struct snd_ctl_elem_value *ucontrol)
3880{
3881 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3882 struct alc_spec *spec = codec->spec;
3883 *ucontrol->value.integer.value = spec->master_sw;
3884 return 0;
3885}
3886
3887static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3888 struct snd_ctl_elem_value *ucontrol)
3889{
3890 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3891 struct alc_spec *spec = codec->spec;
3892 int val = !!*ucontrol->value.integer.value;
3893 hda_nid_t hp, line, mono;
3894
3895 if (val == spec->master_sw)
3896 return 0;
3897 spec->master_sw = val;
3898 hp = (kcontrol->private_value >> 16) & 0xff;
3899 line = (kcontrol->private_value >> 8) & 0xff;
3900 mono = kcontrol->private_value & 0xff;
3901 alc260_hp_master_update(codec, hp, line, mono);
3902 return 1;
3903}
3904
3905static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3906 {
3907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3908 .name = "Master Playback Switch",
3909 .info = snd_ctl_boolean_mono_info,
3910 .get = alc260_hp_master_sw_get,
3911 .put = alc260_hp_master_sw_put,
3912 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
3913 },
3914 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3915 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3917 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3918 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
3919 HDA_OUTPUT),
3920 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3921 { } /* end */
3922};
3923
3924static struct hda_verb alc260_hp_unsol_verbs[] = {
3925 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3926 {},
3927};
3928
3929static void alc260_hp_automute(struct hda_codec *codec)
3930{
3931 struct alc_spec *spec = codec->spec;
3932 unsigned int present;
3933
3934 present = snd_hda_codec_read(codec, 0x10, 0,
3935 AC_VERB_GET_PIN_SENSE, 0);
3936 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3937 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
3938}
3939
3940static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3941{
3942 if ((res >> 26) == ALC880_HP_EVENT)
3943 alc260_hp_automute(codec);
3944}
3945
df694daa 3946static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
3947 {
3948 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3949 .name = "Master Playback Switch",
3950 .info = snd_ctl_boolean_mono_info,
3951 .get = alc260_hp_master_sw_get,
3952 .put = alc260_hp_master_sw_put,
3953 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
3954 },
df694daa
KY
3955 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3956 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3957 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3958 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3959 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
3961 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3962 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
3963 { } /* end */
3964};
3965
bec15c3a
TI
3966static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
3967 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3968 {},
3969};
3970
3971static void alc260_hp_3013_automute(struct hda_codec *codec)
3972{
3973 struct alc_spec *spec = codec->spec;
3974 unsigned int present;
3975
3976 present = snd_hda_codec_read(codec, 0x15, 0,
3977 AC_VERB_GET_PIN_SENSE, 0);
3978 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3979 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
3980}
3981
3982static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
3983 unsigned int res)
3984{
3985 if ((res >> 26) == ALC880_HP_EVENT)
3986 alc260_hp_3013_automute(codec);
3987}
3988
a1e8d2da
JW
3989/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3990 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3991 */
c8b6bf9b 3992static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 3993 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3994 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 3995 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
3996 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3997 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3998 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3999 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4000 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
4001 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4002 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4003 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4004 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4005 { } /* end */
4006};
4007
a1e8d2da
JW
4008/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4009 * versions of the ALC260 don't act on requests to enable mic bias from NID
4010 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4011 * datasheet doesn't mention this restriction. At this stage it's not clear
4012 * whether this behaviour is intentional or is a hardware bug in chip
4013 * revisions available in early 2006. Therefore for now allow the
4014 * "Headphone Jack Mode" control to span all choices, but if it turns out
4015 * that the lack of mic bias for this NID is intentional we could change the
4016 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4017 *
4018 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4019 * don't appear to make the mic bias available from the "line" jack, even
4020 * though the NID used for this jack (0x14) can supply it. The theory is
4021 * that perhaps Acer have included blocking capacitors between the ALC260
4022 * and the output jack. If this turns out to be the case for all such
4023 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4024 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4025 *
4026 * The C20x Tablet series have a mono internal speaker which is controlled
4027 * via the chip's Mono sum widget and pin complex, so include the necessary
4028 * controls for such models. On models without a "mono speaker" the control
4029 * won't do anything.
a1e8d2da 4030 */
0bfc90e9
JW
4031static struct snd_kcontrol_new alc260_acer_mixer[] = {
4032 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4033 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4034 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4035 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4036 HDA_OUTPUT),
31bffaa9 4037 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4038 HDA_INPUT),
0bfc90e9
JW
4039 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4040 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4041 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4042 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4043 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4044 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4045 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4046 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4047 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4048 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4049 { } /* end */
4050};
4051
bc9f98a9
KY
4052/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4053 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4054 */
4055static struct snd_kcontrol_new alc260_will_mixer[] = {
4056 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4057 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4058 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4059 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4060 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4061 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4062 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4063 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4064 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4065 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4066 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4067 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4068 { } /* end */
4069};
4070
4071/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4072 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4073 */
4074static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4075 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4076 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4077 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4078 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4079 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4080 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4081 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4082 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4083 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4084 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4085 { } /* end */
4086};
4087
df694daa
KY
4088/* capture mixer elements */
4089static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4090 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4091 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4092 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4093 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4094 {
4095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4096 /* The multiple "Capture Source" controls confuse alsamixer
4097 * So call somewhat different..
df694daa
KY
4098 */
4099 /* .name = "Capture Source", */
4100 .name = "Input Source",
4101 .count = 2,
4102 .info = alc_mux_enum_info,
4103 .get = alc_mux_enum_get,
4104 .put = alc_mux_enum_put,
4105 },
4106 { } /* end */
4107};
4108
4109static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4110 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4111 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4112 {
4113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4114 /* The multiple "Capture Source" controls confuse alsamixer
4115 * So call somewhat different..
df694daa
KY
4116 */
4117 /* .name = "Capture Source", */
4118 .name = "Input Source",
4119 .count = 1,
a9430dd8
JW
4120 .info = alc_mux_enum_info,
4121 .get = alc_mux_enum_get,
4122 .put = alc_mux_enum_put,
4123 },
4124 { } /* end */
4125};
4126
df694daa
KY
4127/*
4128 * initialization verbs
4129 */
1da177e4
LT
4130static struct hda_verb alc260_init_verbs[] = {
4131 /* Line In pin widget for input */
05acb863 4132 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4133 /* CD pin widget for input */
05acb863 4134 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4135 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4136 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4137 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4138 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4139 /* LINE-2 is used for line-out in rear */
05acb863 4140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4141 /* select line-out */
fd56f2db 4142 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4143 /* LINE-OUT pin */
05acb863 4144 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4145 /* enable HP */
05acb863 4146 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4147 /* enable Mono */
05acb863
TI
4148 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4149 /* mute capture amp left and right */
16ded525 4150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4151 /* set connection select to line in (default select for this ADC) */
4152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4153 /* mute capture amp left and right */
4154 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4155 /* set connection select to line in (default select for this ADC) */
4156 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4157 /* set vol=0 Line-Out mixer amp left and right */
4158 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4159 /* unmute pin widget amp left and right (no gain on this amp) */
4160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4161 /* set vol=0 HP mixer amp left and right */
4162 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4163 /* unmute pin widget amp left and right (no gain on this amp) */
4164 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4165 /* set vol=0 Mono mixer amp left and right */
4166 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4167 /* unmute pin widget amp left and right (no gain on this amp) */
4168 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4169 /* unmute LINE-2 out pin */
4170 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4171 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4172 * Line In 2 = 0x03
4173 */
cb53c626
TI
4174 /* mute analog inputs */
4175 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4176 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4177 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4178 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4179 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4180 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4181 /* mute Front out path */
4182 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4183 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4184 /* mute Headphone out path */
4185 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4186 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4187 /* mute Mono out path */
4188 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4189 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4190 { }
4191};
4192
474167d6 4193#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4194static struct hda_verb alc260_hp_init_verbs[] = {
4195 /* Headphone and output */
4196 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4197 /* mono output */
4198 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4199 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4200 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4201 /* Mic2 (front panel) pin widget for input and vref at 80% */
4202 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4203 /* Line In pin widget for input */
4204 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4205 /* Line-2 pin widget for output */
4206 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4207 /* CD pin widget for input */
4208 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4209 /* unmute amp left and right */
4210 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4211 /* set connection select to line in (default select for this ADC) */
4212 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4213 /* unmute Line-Out mixer amp left and right (volume = 0) */
4214 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4215 /* mute pin widget amp left and right (no gain on this amp) */
4216 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4217 /* unmute HP mixer amp left and right (volume = 0) */
4218 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4219 /* mute pin widget amp left and right (no gain on this amp) */
4220 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4221 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4222 * Line In 2 = 0x03
4223 */
cb53c626
TI
4224 /* mute analog inputs */
4225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4230 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4231 /* Unmute Front out path */
4232 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4234 /* Unmute Headphone out path */
4235 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4236 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4237 /* Unmute Mono out path */
4238 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4239 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4240 { }
4241};
474167d6 4242#endif
df694daa
KY
4243
4244static struct hda_verb alc260_hp_3013_init_verbs[] = {
4245 /* Line out and output */
4246 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4247 /* mono output */
4248 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4249 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4250 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4251 /* Mic2 (front panel) pin widget for input and vref at 80% */
4252 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4253 /* Line In pin widget for input */
4254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4255 /* Headphone pin widget for output */
4256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4257 /* CD pin widget for input */
4258 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4259 /* unmute amp left and right */
4260 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4261 /* set connection select to line in (default select for this ADC) */
4262 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4263 /* unmute Line-Out mixer amp left and right (volume = 0) */
4264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4265 /* mute pin widget amp left and right (no gain on this amp) */
4266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4267 /* unmute HP mixer amp left and right (volume = 0) */
4268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4269 /* mute pin widget amp left and right (no gain on this amp) */
4270 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4271 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4272 * Line In 2 = 0x03
4273 */
cb53c626
TI
4274 /* mute analog inputs */
4275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4280 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4281 /* Unmute Front out path */
4282 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4283 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4284 /* Unmute Headphone out path */
4285 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4287 /* Unmute Mono out path */
4288 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4289 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4290 { }
4291};
4292
a9430dd8 4293/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4294 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4295 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4296 */
4297static struct hda_verb alc260_fujitsu_init_verbs[] = {
4298 /* Disable all GPIOs */
4299 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4300 /* Internal speaker is connected to headphone pin */
4301 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4302 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4304 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4306 /* Ensure all other unused pins are disabled and muted. */
4307 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4309 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4310 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4311 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4312 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4315
4316 /* Disable digital (SPDIF) pins */
4317 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4318 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4319
f7ace40d
JW
4320 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4321 * when acting as an output.
4322 */
4323 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4324
f7ace40d 4325 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4327 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4328 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4329 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4330 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4332 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4333 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4334 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4335
f7ace40d
JW
4336 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4337 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4338 /* Unmute Line1 pin widget output buffer since it starts as an output.
4339 * If the pin mode is changed by the user the pin mode control will
4340 * take care of enabling the pin's input/output buffers as needed.
4341 * Therefore there's no need to enable the input buffer at this
4342 * stage.
cdcd9268 4343 */
f7ace40d 4344 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4345 /* Unmute input buffer of pin widget used for Line-in (no equiv
4346 * mixer ctrl)
4347 */
f7ace40d
JW
4348 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4349
4350 /* Mute capture amp left and right */
4351 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4352 /* Set ADC connection select to match default mixer setting - line
4353 * in (on mic1 pin)
4354 */
4355 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4356
4357 /* Do the same for the second ADC: mute capture input amp and
4358 * set ADC connection to line in (on mic1 pin)
4359 */
4360 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4361 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4362
4363 /* Mute all inputs to mixer widget (even unconnected ones) */
4364 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4366 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4368 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4370 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4371 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4372
4373 { }
a9430dd8
JW
4374};
4375
0bfc90e9
JW
4376/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4377 * similar laptops (adapted from Fujitsu init verbs).
4378 */
4379static struct hda_verb alc260_acer_init_verbs[] = {
4380 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4381 * the headphone jack. Turn this on and rely on the standard mute
4382 * methods whenever the user wants to turn these outputs off.
4383 */
4384 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4385 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4386 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4387 /* Internal speaker/Headphone jack is connected to Line-out pin */
4388 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4389 /* Internal microphone/Mic jack is connected to Mic1 pin */
4390 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4391 /* Line In jack is connected to Line1 pin */
4392 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4393 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4394 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4395 /* Ensure all other unused pins are disabled and muted. */
4396 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4397 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4398 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4399 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4402 /* Disable digital (SPDIF) pins */
4403 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4404 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4405
4406 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4407 * bus when acting as outputs.
4408 */
4409 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4410 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4411
4412 /* Start with output sum widgets muted and their output gains at min */
4413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4415 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4417 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4418 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4419 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4420 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4421 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4422
f12ab1e0
TI
4423 /* Unmute Line-out pin widget amp left and right
4424 * (no equiv mixer ctrl)
4425 */
0bfc90e9 4426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4427 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4428 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4429 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4430 * inputs. If the pin mode is changed by the user the pin mode control
4431 * will take care of enabling the pin's input/output buffers as needed.
4432 * Therefore there's no need to enable the input buffer at this
4433 * stage.
4434 */
4435 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4436 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4437
4438 /* Mute capture amp left and right */
4439 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4440 /* Set ADC connection select to match default mixer setting - mic
4441 * (on mic1 pin)
4442 */
4443 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4444
4445 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4446 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4447 */
4448 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4449 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4450
4451 /* Mute all inputs to mixer widget (even unconnected ones) */
4452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4460
4461 { }
4462};
4463
bc9f98a9
KY
4464static struct hda_verb alc260_will_verbs[] = {
4465 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4466 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4467 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4468 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4469 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4470 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4471 {}
4472};
4473
4474static struct hda_verb alc260_replacer_672v_verbs[] = {
4475 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4476 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4477 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4478
4479 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4480 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4481 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4482
4483 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4484 {}
4485};
4486
4487/* toggle speaker-output according to the hp-jack state */
4488static void alc260_replacer_672v_automute(struct hda_codec *codec)
4489{
4490 unsigned int present;
4491
4492 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4493 present = snd_hda_codec_read(codec, 0x0f, 0,
4494 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4495 if (present) {
82beb8fd
TI
4496 snd_hda_codec_write_cache(codec, 0x01, 0,
4497 AC_VERB_SET_GPIO_DATA, 1);
4498 snd_hda_codec_write_cache(codec, 0x0f, 0,
4499 AC_VERB_SET_PIN_WIDGET_CONTROL,
4500 PIN_HP);
bc9f98a9 4501 } else {
82beb8fd
TI
4502 snd_hda_codec_write_cache(codec, 0x01, 0,
4503 AC_VERB_SET_GPIO_DATA, 0);
4504 snd_hda_codec_write_cache(codec, 0x0f, 0,
4505 AC_VERB_SET_PIN_WIDGET_CONTROL,
4506 PIN_OUT);
bc9f98a9
KY
4507 }
4508}
4509
4510static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4511 unsigned int res)
4512{
4513 if ((res >> 26) == ALC880_HP_EVENT)
4514 alc260_replacer_672v_automute(codec);
4515}
4516
7cf51e48
JW
4517/* Test configuration for debugging, modelled after the ALC880 test
4518 * configuration.
4519 */
4520#ifdef CONFIG_SND_DEBUG
4521static hda_nid_t alc260_test_dac_nids[1] = {
4522 0x02,
4523};
4524static hda_nid_t alc260_test_adc_nids[2] = {
4525 0x04, 0x05,
4526};
a1e8d2da
JW
4527/* For testing the ALC260, each input MUX needs its own definition since
4528 * the signal assignments are different. This assumes that the first ADC
4529 * is NID 0x04.
17e7aec6 4530 */
a1e8d2da
JW
4531static struct hda_input_mux alc260_test_capture_sources[2] = {
4532 {
4533 .num_items = 7,
4534 .items = {
4535 { "MIC1 pin", 0x0 },
4536 { "MIC2 pin", 0x1 },
4537 { "LINE1 pin", 0x2 },
4538 { "LINE2 pin", 0x3 },
4539 { "CD pin", 0x4 },
4540 { "LINE-OUT pin", 0x5 },
4541 { "HP-OUT pin", 0x6 },
4542 },
4543 },
4544 {
4545 .num_items = 8,
4546 .items = {
4547 { "MIC1 pin", 0x0 },
4548 { "MIC2 pin", 0x1 },
4549 { "LINE1 pin", 0x2 },
4550 { "LINE2 pin", 0x3 },
4551 { "CD pin", 0x4 },
4552 { "Mixer", 0x5 },
4553 { "LINE-OUT pin", 0x6 },
4554 { "HP-OUT pin", 0x7 },
4555 },
7cf51e48
JW
4556 },
4557};
4558static struct snd_kcontrol_new alc260_test_mixer[] = {
4559 /* Output driver widgets */
4560 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4561 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4562 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4563 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4564 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4565 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4566
a1e8d2da
JW
4567 /* Modes for retasking pin widgets
4568 * Note: the ALC260 doesn't seem to act on requests to enable mic
4569 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4570 * mention this restriction. At this stage it's not clear whether
4571 * this behaviour is intentional or is a hardware bug in chip
4572 * revisions available at least up until early 2006. Therefore for
4573 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4574 * choices, but if it turns out that the lack of mic bias for these
4575 * NIDs is intentional we could change their modes from
4576 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4577 */
7cf51e48
JW
4578 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4579 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4580 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4581 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4582 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4583 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4584
4585 /* Loopback mixer controls */
4586 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4587 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4588 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4589 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4590 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4591 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4592 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4593 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4594 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4595 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4596 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4597 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4598 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4599 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4600 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4601 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4602
4603 /* Controls for GPIO pins, assuming they are configured as outputs */
4604 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4605 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4606 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4607 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4608
92621f13
JW
4609 /* Switches to allow the digital IO pins to be enabled. The datasheet
4610 * is ambigious as to which NID is which; testing on laptops which
4611 * make this output available should provide clarification.
4612 */
4613 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4614 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4615
f8225f6d
JW
4616 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4617 * this output to turn on an external amplifier.
4618 */
4619 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4620 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4621
7cf51e48
JW
4622 { } /* end */
4623};
4624static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4625 /* Enable all GPIOs as outputs with an initial value of 0 */
4626 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4627 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4628 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4629
7cf51e48
JW
4630 /* Enable retasking pins as output, initially without power amp */
4631 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4632 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4634 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4635 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4636 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4637
92621f13
JW
4638 /* Disable digital (SPDIF) pins initially, but users can enable
4639 * them via a mixer switch. In the case of SPDIF-out, this initverb
4640 * payload also sets the generation to 0, output to be in "consumer"
4641 * PCM format, copyright asserted, no pre-emphasis and no validity
4642 * control.
4643 */
7cf51e48
JW
4644 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4645 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4646
f7ace40d 4647 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4648 * OUT1 sum bus when acting as an output.
4649 */
4650 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4651 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4652 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4653 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4654
4655 /* Start with output sum widgets muted and their output gains at min */
4656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4657 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4658 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4660 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4661 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4663 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4664 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4665
cdcd9268
JW
4666 /* Unmute retasking pin widget output buffers since the default
4667 * state appears to be output. As the pin mode is changed by the
4668 * user the pin mode control will take care of enabling the pin's
4669 * input/output buffers as needed.
4670 */
7cf51e48
JW
4671 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4674 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4675 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4676 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4677 /* Also unmute the mono-out pin widget */
4678 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4679
7cf51e48
JW
4680 /* Mute capture amp left and right */
4681 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4682 /* Set ADC connection select to match default mixer setting (mic1
4683 * pin)
7cf51e48
JW
4684 */
4685 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4686
4687 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4688 * set ADC connection to mic1 pin
7cf51e48
JW
4689 */
4690 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4691 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4692
4693 /* Mute all inputs to mixer widget (even unconnected ones) */
4694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4696 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4697 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4700 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4701 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4702
4703 { }
4704};
4705#endif
4706
6330079f
TI
4707#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4708#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 4709
a3bcba38
TI
4710#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4711#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4712
df694daa
KY
4713/*
4714 * for BIOS auto-configuration
4715 */
16ded525 4716
df694daa
KY
4717static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4718 const char *pfx)
4719{
4720 hda_nid_t nid_vol;
4721 unsigned long vol_val, sw_val;
4722 char name[32];
4723 int err;
4724
4725 if (nid >= 0x0f && nid < 0x11) {
4726 nid_vol = nid - 0x7;
4727 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4728 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4729 } else if (nid == 0x11) {
4730 nid_vol = nid - 0x7;
4731 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4732 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4733 } else if (nid >= 0x12 && nid <= 0x15) {
4734 nid_vol = 0x08;
4735 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4736 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4737 } else
4738 return 0; /* N/A */
4739
4740 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4741 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4742 if (err < 0)
df694daa
KY
4743 return err;
4744 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4745 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4746 if (err < 0)
df694daa
KY
4747 return err;
4748 return 1;
4749}
4750
4751/* add playback controls from the parsed DAC table */
4752static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4753 const struct auto_pin_cfg *cfg)
4754{
4755 hda_nid_t nid;
4756 int err;
4757
4758 spec->multiout.num_dacs = 1;
4759 spec->multiout.dac_nids = spec->private_dac_nids;
4760 spec->multiout.dac_nids[0] = 0x02;
4761
4762 nid = cfg->line_out_pins[0];
4763 if (nid) {
4764 err = alc260_add_playback_controls(spec, nid, "Front");
4765 if (err < 0)
4766 return err;
4767 }
4768
82bc955f 4769 nid = cfg->speaker_pins[0];
df694daa
KY
4770 if (nid) {
4771 err = alc260_add_playback_controls(spec, nid, "Speaker");
4772 if (err < 0)
4773 return err;
4774 }
4775
eb06ed8f 4776 nid = cfg->hp_pins[0];
df694daa
KY
4777 if (nid) {
4778 err = alc260_add_playback_controls(spec, nid, "Headphone");
4779 if (err < 0)
4780 return err;
4781 }
f12ab1e0 4782 return 0;
df694daa
KY
4783}
4784
4785/* create playback/capture controls for input pins */
4786static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4787 const struct auto_pin_cfg *cfg)
4788{
df694daa
KY
4789 struct hda_input_mux *imux = &spec->private_imux;
4790 int i, err, idx;
4791
4792 for (i = 0; i < AUTO_PIN_LAST; i++) {
4793 if (cfg->input_pins[i] >= 0x12) {
4794 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4795 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4796 auto_pin_cfg_labels[i], idx,
4797 0x07);
df694daa
KY
4798 if (err < 0)
4799 return err;
f12ab1e0
TI
4800 imux->items[imux->num_items].label =
4801 auto_pin_cfg_labels[i];
df694daa
KY
4802 imux->items[imux->num_items].index = idx;
4803 imux->num_items++;
4804 }
f12ab1e0 4805 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4806 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4807 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4808 auto_pin_cfg_labels[i], idx,
4809 0x07);
df694daa
KY
4810 if (err < 0)
4811 return err;
f12ab1e0
TI
4812 imux->items[imux->num_items].label =
4813 auto_pin_cfg_labels[i];
df694daa
KY
4814 imux->items[imux->num_items].index = idx;
4815 imux->num_items++;
4816 }
4817 }
4818 return 0;
4819}
4820
4821static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4822 hda_nid_t nid, int pin_type,
4823 int sel_idx)
4824{
f6c7e546 4825 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
4826 /* need the manual connection? */
4827 if (nid >= 0x12) {
4828 int idx = nid - 0x12;
4829 snd_hda_codec_write(codec, idx + 0x0b, 0,
4830 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4831 }
4832}
4833
4834static void alc260_auto_init_multi_out(struct hda_codec *codec)
4835{
4836 struct alc_spec *spec = codec->spec;
4837 hda_nid_t nid;
4838
bc9f98a9 4839 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4840 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4841 if (nid) {
4842 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4843 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4844 }
df694daa 4845
82bc955f 4846 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4847 if (nid)
4848 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4849
eb06ed8f 4850 nid = spec->autocfg.hp_pins[0];
df694daa 4851 if (nid)
baba8ee9 4852 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4853}
df694daa
KY
4854
4855#define ALC260_PIN_CD_NID 0x16
4856static void alc260_auto_init_analog_input(struct hda_codec *codec)
4857{
4858 struct alc_spec *spec = codec->spec;
4859 int i;
4860
4861 for (i = 0; i < AUTO_PIN_LAST; i++) {
4862 hda_nid_t nid = spec->autocfg.input_pins[i];
4863 if (nid >= 0x12) {
f12ab1e0
TI
4864 snd_hda_codec_write(codec, nid, 0,
4865 AC_VERB_SET_PIN_WIDGET_CONTROL,
4866 i <= AUTO_PIN_FRONT_MIC ?
4867 PIN_VREF80 : PIN_IN);
df694daa 4868 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4869 snd_hda_codec_write(codec, nid, 0,
4870 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4871 AMP_OUT_MUTE);
4872 }
4873 }
4874}
4875
4876/*
4877 * generic initialization of ADC, input mixers and output mixers
4878 */
4879static struct hda_verb alc260_volume_init_verbs[] = {
4880 /*
4881 * Unmute ADC0-1 and set the default input to mic-in
4882 */
4883 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4885 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4886 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4887
4888 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4889 * mixer widget
f12ab1e0
TI
4890 * Note: PASD motherboards uses the Line In 2 as the input for
4891 * front panel mic (mic 2)
df694daa
KY
4892 */
4893 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4894 /* mute analog inputs */
4895 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4900
4901 /*
4902 * Set up output mixers (0x08 - 0x0a)
4903 */
4904 /* set vol=0 to output mixers */
4905 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4908 /* set up input amps for analog loopback */
4909 /* Amp Indices: DAC = 0, mixer = 1 */
4910 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4911 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4912 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4913 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4914 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4915 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4916
4917 { }
4918};
4919
4920static int alc260_parse_auto_config(struct hda_codec *codec)
4921{
4922 struct alc_spec *spec = codec->spec;
4923 unsigned int wcap;
4924 int err;
4925 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4926
f12ab1e0
TI
4927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4928 alc260_ignore);
4929 if (err < 0)
df694daa 4930 return err;
f12ab1e0
TI
4931 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4932 if (err < 0)
4a471b7d 4933 return err;
f12ab1e0 4934 if (!spec->kctl_alloc)
df694daa 4935 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
4936 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4937 if (err < 0)
df694daa
KY
4938 return err;
4939
4940 spec->multiout.max_channels = 2;
4941
4942 if (spec->autocfg.dig_out_pin)
4943 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4944 if (spec->kctl_alloc)
4945 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4946
4947 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4948
a1e8d2da 4949 spec->num_mux_defs = 1;
df694daa
KY
4950 spec->input_mux = &spec->private_imux;
4951
4952 /* check whether NID 0x04 is valid */
4a471b7d 4953 wcap = get_wcaps(codec, 0x04);
df694daa 4954 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
67ebcb03 4955 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
df694daa
KY
4956 spec->adc_nids = alc260_adc_nids_alt;
4957 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4958 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
4959 } else {
4960 spec->adc_nids = alc260_adc_nids;
4961 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4962 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 4963 }
4a471b7d 4964 spec->num_mixers++;
df694daa
KY
4965
4966 return 1;
4967}
4968
ae6b813a
TI
4969/* additional initialization for auto-configuration model */
4970static void alc260_auto_init(struct hda_codec *codec)
df694daa 4971{
f6c7e546 4972 struct alc_spec *spec = codec->spec;
df694daa
KY
4973 alc260_auto_init_multi_out(codec);
4974 alc260_auto_init_analog_input(codec);
f6c7e546
TI
4975 if (spec->unsol_event)
4976 alc_sku_automute(codec);
df694daa
KY
4977}
4978
cb53c626
TI
4979#ifdef CONFIG_SND_HDA_POWER_SAVE
4980static struct hda_amp_list alc260_loopbacks[] = {
4981 { 0x07, HDA_INPUT, 0 },
4982 { 0x07, HDA_INPUT, 1 },
4983 { 0x07, HDA_INPUT, 2 },
4984 { 0x07, HDA_INPUT, 3 },
4985 { 0x07, HDA_INPUT, 4 },
4986 { } /* end */
4987};
4988#endif
4989
df694daa
KY
4990/*
4991 * ALC260 configurations
4992 */
f5fcc13c
TI
4993static const char *alc260_models[ALC260_MODEL_LAST] = {
4994 [ALC260_BASIC] = "basic",
4995 [ALC260_HP] = "hp",
4996 [ALC260_HP_3013] = "hp-3013",
4997 [ALC260_FUJITSU_S702X] = "fujitsu",
4998 [ALC260_ACER] = "acer",
bc9f98a9
KY
4999 [ALC260_WILL] = "will",
5000 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 5001#ifdef CONFIG_SND_DEBUG
f5fcc13c 5002 [ALC260_TEST] = "test",
7cf51e48 5003#endif
f5fcc13c
TI
5004 [ALC260_AUTO] = "auto",
5005};
5006
5007static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5008 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5009 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5010 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5011 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
5012 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5013 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5014 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5015 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5016 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5017 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5018 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5019 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5020 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5021 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5022 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5023 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5024 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5025 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5026 {}
5027};
5028
5029static struct alc_config_preset alc260_presets[] = {
5030 [ALC260_BASIC] = {
5031 .mixers = { alc260_base_output_mixer,
5032 alc260_input_mixer,
5033 alc260_pc_beep_mixer,
5034 alc260_capture_mixer },
5035 .init_verbs = { alc260_init_verbs },
5036 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5037 .dac_nids = alc260_dac_nids,
5038 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5039 .adc_nids = alc260_adc_nids,
5040 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5041 .channel_mode = alc260_modes,
5042 .input_mux = &alc260_capture_source,
5043 },
5044 [ALC260_HP] = {
bec15c3a 5045 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5046 alc260_input_mixer,
5047 alc260_capture_alt_mixer },
bec15c3a
TI
5048 .init_verbs = { alc260_init_verbs,
5049 alc260_hp_unsol_verbs },
df694daa
KY
5050 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5051 .dac_nids = alc260_dac_nids,
5052 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5053 .adc_nids = alc260_hp_adc_nids,
5054 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5055 .channel_mode = alc260_modes,
5056 .input_mux = &alc260_capture_source,
bec15c3a
TI
5057 .unsol_event = alc260_hp_unsol_event,
5058 .init_hook = alc260_hp_automute,
df694daa
KY
5059 },
5060 [ALC260_HP_3013] = {
5061 .mixers = { alc260_hp_3013_mixer,
5062 alc260_input_mixer,
5063 alc260_capture_alt_mixer },
bec15c3a
TI
5064 .init_verbs = { alc260_hp_3013_init_verbs,
5065 alc260_hp_3013_unsol_verbs },
df694daa
KY
5066 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5067 .dac_nids = alc260_dac_nids,
5068 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5069 .adc_nids = alc260_hp_adc_nids,
5070 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5071 .channel_mode = alc260_modes,
5072 .input_mux = &alc260_capture_source,
bec15c3a
TI
5073 .unsol_event = alc260_hp_3013_unsol_event,
5074 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5075 },
5076 [ALC260_FUJITSU_S702X] = {
5077 .mixers = { alc260_fujitsu_mixer,
5078 alc260_capture_mixer },
5079 .init_verbs = { alc260_fujitsu_init_verbs },
5080 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5081 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5082 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5083 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5084 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5085 .channel_mode = alc260_modes,
a1e8d2da
JW
5086 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5087 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5088 },
0bfc90e9
JW
5089 [ALC260_ACER] = {
5090 .mixers = { alc260_acer_mixer,
5091 alc260_capture_mixer },
5092 .init_verbs = { alc260_acer_init_verbs },
5093 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5094 .dac_nids = alc260_dac_nids,
5095 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5096 .adc_nids = alc260_dual_adc_nids,
5097 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5098 .channel_mode = alc260_modes,
a1e8d2da
JW
5099 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5100 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5101 },
bc9f98a9
KY
5102 [ALC260_WILL] = {
5103 .mixers = { alc260_will_mixer,
5104 alc260_capture_mixer },
5105 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5106 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5107 .dac_nids = alc260_dac_nids,
5108 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5109 .adc_nids = alc260_adc_nids,
5110 .dig_out_nid = ALC260_DIGOUT_NID,
5111 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5112 .channel_mode = alc260_modes,
5113 .input_mux = &alc260_capture_source,
5114 },
5115 [ALC260_REPLACER_672V] = {
5116 .mixers = { alc260_replacer_672v_mixer,
5117 alc260_capture_mixer },
5118 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5119 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5120 .dac_nids = alc260_dac_nids,
5121 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5122 .adc_nids = alc260_adc_nids,
5123 .dig_out_nid = ALC260_DIGOUT_NID,
5124 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5125 .channel_mode = alc260_modes,
5126 .input_mux = &alc260_capture_source,
5127 .unsol_event = alc260_replacer_672v_unsol_event,
5128 .init_hook = alc260_replacer_672v_automute,
5129 },
7cf51e48
JW
5130#ifdef CONFIG_SND_DEBUG
5131 [ALC260_TEST] = {
5132 .mixers = { alc260_test_mixer,
5133 alc260_capture_mixer },
5134 .init_verbs = { alc260_test_init_verbs },
5135 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5136 .dac_nids = alc260_test_dac_nids,
5137 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5138 .adc_nids = alc260_test_adc_nids,
5139 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5140 .channel_mode = alc260_modes,
a1e8d2da
JW
5141 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5142 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5143 },
5144#endif
df694daa
KY
5145};
5146
5147static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5148{
5149 struct alc_spec *spec;
df694daa 5150 int err, board_config;
1da177e4 5151
e560d8d8 5152 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5153 if (spec == NULL)
5154 return -ENOMEM;
5155
5156 codec->spec = spec;
5157
f5fcc13c
TI
5158 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5159 alc260_models,
5160 alc260_cfg_tbl);
5161 if (board_config < 0) {
9c7f852e
TI
5162 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5163 "trying auto-probe from BIOS...\n");
df694daa 5164 board_config = ALC260_AUTO;
16ded525 5165 }
1da177e4 5166
df694daa
KY
5167 if (board_config == ALC260_AUTO) {
5168 /* automatic parse from the BIOS config */
5169 err = alc260_parse_auto_config(codec);
5170 if (err < 0) {
5171 alc_free(codec);
5172 return err;
f12ab1e0 5173 } else if (!err) {
9c7f852e
TI
5174 printk(KERN_INFO
5175 "hda_codec: Cannot set up configuration "
5176 "from BIOS. Using base mode...\n");
df694daa
KY
5177 board_config = ALC260_BASIC;
5178 }
a9430dd8 5179 }
e9edcee0 5180
df694daa
KY
5181 if (board_config != ALC260_AUTO)
5182 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5183
5184 spec->stream_name_analog = "ALC260 Analog";
5185 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5186 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5187
a3bcba38
TI
5188 spec->stream_name_digital = "ALC260 Digital";
5189 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5190 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5191
2134ea4f
TI
5192 spec->vmaster_nid = 0x08;
5193
1da177e4 5194 codec->patch_ops = alc_patch_ops;
df694daa 5195 if (board_config == ALC260_AUTO)
ae6b813a 5196 spec->init_hook = alc260_auto_init;
cb53c626
TI
5197#ifdef CONFIG_SND_HDA_POWER_SAVE
5198 if (!spec->loopback.amplist)
5199 spec->loopback.amplist = alc260_loopbacks;
5200#endif
1da177e4
LT
5201
5202 return 0;
5203}
5204
e9edcee0 5205
1da177e4
LT
5206/*
5207 * ALC882 support
5208 *
5209 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5210 * configuration. Each pin widget can choose any input DACs and a mixer.
5211 * Each ADC is connected from a mixer of all inputs. This makes possible
5212 * 6-channel independent captures.
5213 *
5214 * In addition, an independent DAC for the multi-playback (not used in this
5215 * driver yet).
5216 */
df694daa
KY
5217#define ALC882_DIGOUT_NID 0x06
5218#define ALC882_DIGIN_NID 0x0a
1da177e4 5219
d2a6d7dc 5220static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5221 { 8, NULL }
5222};
5223
5224static hda_nid_t alc882_dac_nids[4] = {
5225 /* front, rear, clfe, rear_surr */
5226 0x02, 0x03, 0x04, 0x05
5227};
5228
df694daa
KY
5229/* identical with ALC880 */
5230#define alc882_adc_nids alc880_adc_nids
5231#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5232
e1406348
TI
5233static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5234static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5235
1da177e4
LT
5236/* input MUX */
5237/* FIXME: should be a matrix-type input source selection */
5238
5239static struct hda_input_mux alc882_capture_source = {
5240 .num_items = 4,
5241 .items = {
5242 { "Mic", 0x0 },
5243 { "Front Mic", 0x1 },
5244 { "Line", 0x2 },
5245 { "CD", 0x4 },
5246 },
5247};
1da177e4
LT
5248#define alc882_mux_enum_info alc_mux_enum_info
5249#define alc882_mux_enum_get alc_mux_enum_get
5250
f12ab1e0
TI
5251static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5252 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5253{
5254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5255 struct alc_spec *spec = codec->spec;
5256 const struct hda_input_mux *imux = spec->input_mux;
5257 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
88c71a99
TI
5258 hda_nid_t nid = spec->capsrc_nids ?
5259 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4
LT
5260 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5261 unsigned int i, idx;
5262
5263 idx = ucontrol->value.enumerated.item[0];
5264 if (idx >= imux->num_items)
5265 idx = imux->num_items - 1;
82beb8fd 5266 if (*cur_val == idx)
1da177e4
LT
5267 return 0;
5268 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5269 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5270 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5271 imux->items[i].index,
47fd830a 5272 HDA_AMP_MUTE, v);
1da177e4
LT
5273 }
5274 *cur_val = idx;
5275 return 1;
5276}
5277
272a527c
KY
5278/*
5279 * 2ch mode
5280 */
5281static struct hda_verb alc882_3ST_ch2_init[] = {
5282 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5283 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5284 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5285 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5286 { } /* end */
5287};
5288
5289/*
5290 * 6ch mode
5291 */
5292static struct hda_verb alc882_3ST_ch6_init[] = {
5293 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5294 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5295 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5296 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5297 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5298 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5299 { } /* end */
5300};
5301
5302static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5303 { 2, alc882_3ST_ch2_init },
5304 { 6, alc882_3ST_ch6_init },
5305};
5306
df694daa
KY
5307/*
5308 * 6ch mode
5309 */
5310static struct hda_verb alc882_sixstack_ch6_init[] = {
5311 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5312 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5313 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5314 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5315 { } /* end */
5316};
5317
5318/*
5319 * 8ch mode
5320 */
5321static struct hda_verb alc882_sixstack_ch8_init[] = {
5322 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5323 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5324 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5325 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5326 { } /* end */
5327};
5328
5329static struct hda_channel_mode alc882_sixstack_modes[2] = {
5330 { 6, alc882_sixstack_ch6_init },
5331 { 8, alc882_sixstack_ch8_init },
5332};
5333
87350ad0
TI
5334/*
5335 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5336 */
5337
5338/*
5339 * 2ch mode
5340 */
5341static struct hda_verb alc885_mbp_ch2_init[] = {
5342 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5343 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5344 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5345 { } /* end */
5346};
5347
5348/*
5349 * 6ch mode
5350 */
5351static struct hda_verb alc885_mbp_ch6_init[] = {
5352 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5353 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5354 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5355 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5356 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5357 { } /* end */
5358};
5359
5360static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5361 { 2, alc885_mbp_ch2_init },
5362 { 6, alc885_mbp_ch6_init },
5363};
5364
5365
1da177e4
LT
5366/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5367 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5368 */
c8b6bf9b 5369static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5371 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5372 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5373 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5374 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5375 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5376 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5377 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5378 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5379 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5381 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5382 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5383 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5384 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5385 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5386 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5387 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5388 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5389 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5391 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5392 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5393 { } /* end */
5394};
5395
87350ad0 5396static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5398 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5399 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5400 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5402 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5404 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5405 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5406 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5407 { } /* end */
5408};
bdd148a3
KY
5409static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5410 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5411 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5412 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5413 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5417 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5419 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5420 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5421 { } /* end */
5422};
5423
272a527c
KY
5424static struct snd_kcontrol_new alc882_targa_mixer[] = {
5425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5426 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5428 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5429 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5430 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5431 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5432 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5434 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5435 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5437 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5438 { } /* end */
5439};
5440
5441/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5442 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5443 */
5444static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5445 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5446 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5448 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5453 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5454 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5457 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5458 { } /* end */
5459};
5460
914759b7
TI
5461static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5465 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5466 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5467 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5468 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5469 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5470 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5471 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5472 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5473 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5474 { } /* end */
5475};
5476
df694daa
KY
5477static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5478 {
5479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5480 .name = "Channel Mode",
5481 .info = alc_ch_mode_info,
5482 .get = alc_ch_mode_get,
5483 .put = alc_ch_mode_put,
5484 },
5485 { } /* end */
5486};
5487
1da177e4
LT
5488static struct hda_verb alc882_init_verbs[] = {
5489 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5490 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5491 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5492 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5493 /* Rear mixer */
05acb863
TI
5494 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5495 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5496 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5497 /* CLFE mixer */
05acb863
TI
5498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5500 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5501 /* Side mixer */
05acb863
TI
5502 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5503 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5504 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5505
e9edcee0 5506 /* Front Pin: output 0 (0x0c) */
05acb863 5507 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5508 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5509 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5510 /* Rear Pin: output 1 (0x0d) */
05acb863 5511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5512 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5514 /* CLFE Pin: output 2 (0x0e) */
05acb863 5515 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5516 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5517 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5518 /* Side Pin: output 3 (0x0f) */
05acb863 5519 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5520 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5521 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5522 /* Mic (rear) pin: input vref at 80% */
16ded525 5523 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5524 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5525 /* Front Mic pin: input vref at 80% */
16ded525 5526 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5527 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5528 /* Line In pin: input */
05acb863 5529 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5530 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5531 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5533 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5534 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5535 /* CD pin widget for input */
05acb863 5536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5537
5538 /* FIXME: use matrix-type input source selection */
5539 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5540 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5545 /* Input mixer2 */
05acb863
TI
5546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5547 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5549 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5550 /* Input mixer3 */
05acb863
TI
5551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5552 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5554 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5555 /* ADC1: mute amp left and right */
5556 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5557 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5558 /* ADC2: mute amp left and right */
5559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5561 /* ADC3: mute amp left and right */
5562 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5563 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5564
5565 { }
5566};
5567
4b146cb0
TI
5568static struct hda_verb alc882_eapd_verbs[] = {
5569 /* change to EAPD mode */
5570 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5571 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5572 { }
4b146cb0
TI
5573};
5574
9102cd1c
TD
5575/* Mac Pro test */
5576static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5577 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5578 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5580 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5581 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5582 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5583 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5584 { } /* end */
5585};
5586
5587static struct hda_verb alc882_macpro_init_verbs[] = {
5588 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5591 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5592 /* Front Pin: output 0 (0x0c) */
5593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5594 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5596 /* Front Mic pin: input vref at 80% */
5597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5599 /* Speaker: output */
5600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5602 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5603 /* Headphone output (output 0 - 0x0c) */
5604 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5605 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5606 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5607
5608 /* FIXME: use matrix-type input source selection */
5609 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5610 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5615 /* Input mixer2 */
5616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5619 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5620 /* Input mixer3 */
5621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5625 /* ADC1: mute amp left and right */
5626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5627 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5628 /* ADC2: mute amp left and right */
5629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5630 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5631 /* ADC3: mute amp left and right */
5632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5633 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5634
5635 { }
5636};
f12ab1e0 5637
87350ad0
TI
5638/* Macbook Pro rev3 */
5639static struct hda_verb alc885_mbp3_init_verbs[] = {
5640 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5642 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5643 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5644 /* Rear mixer */
5645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5647 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5648 /* Front Pin: output 0 (0x0c) */
5649 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5651 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5652 /* HP Pin: output 0 (0x0d) */
5653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5655 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5656 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5657 /* Mic (rear) pin: input vref at 80% */
5658 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5659 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5660 /* Front Mic pin: input vref at 80% */
5661 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5662 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5663 /* Line In pin: use output 1 when in LineOut mode */
5664 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5665 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5666 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5667
5668 /* FIXME: use matrix-type input source selection */
5669 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5670 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5675 /* Input mixer2 */
5676 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5677 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5680 /* Input mixer3 */
5681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5683 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5684 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5685 /* ADC1: mute amp left and right */
5686 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5687 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5688 /* ADC2: mute amp left and right */
5689 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5690 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5691 /* ADC3: mute amp left and right */
5692 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5693 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5694
5695 { }
5696};
5697
c54728d8
NF
5698/* iMac 24 mixer. */
5699static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5700 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5701 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5702 { } /* end */
5703};
5704
5705/* iMac 24 init verbs. */
5706static struct hda_verb alc885_imac24_init_verbs[] = {
5707 /* Internal speakers: output 0 (0x0c) */
5708 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5710 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5711 /* Internal speakers: output 0 (0x0c) */
5712 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5713 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5714 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5715 /* Headphone: output 0 (0x0c) */
5716 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5718 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5719 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5720 /* Front Mic: input vref at 80% */
5721 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5722 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5723 { }
5724};
5725
5726/* Toggle speaker-output according to the hp-jack state */
5727static void alc885_imac24_automute(struct hda_codec *codec)
5728{
5729 unsigned int present;
5730
5731 present = snd_hda_codec_read(codec, 0x14, 0,
5732 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5733 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5734 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5735 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5736 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5737}
5738
5739/* Processes unsolicited events. */
5740static void alc885_imac24_unsol_event(struct hda_codec *codec,
5741 unsigned int res)
5742{
5743 /* Headphone insertion or removal. */
5744 if ((res >> 26) == ALC880_HP_EVENT)
5745 alc885_imac24_automute(codec);
5746}
5747
87350ad0
TI
5748static void alc885_mbp3_automute(struct hda_codec *codec)
5749{
5750 unsigned int present;
5751
5752 present = snd_hda_codec_read(codec, 0x15, 0,
5753 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5754 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5755 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5756 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5757 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5758
5759}
5760static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5761 unsigned int res)
5762{
5763 /* Headphone insertion or removal. */
5764 if ((res >> 26) == ALC880_HP_EVENT)
5765 alc885_mbp3_automute(codec);
5766}
5767
5768
272a527c
KY
5769static struct hda_verb alc882_targa_verbs[] = {
5770 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5771 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5772
5773 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5774 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5775
5776 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5777 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5778 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5779
5780 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5781 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5782 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5783 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5784 { } /* end */
5785};
5786
5787/* toggle speaker-output according to the hp-jack state */
5788static void alc882_targa_automute(struct hda_codec *codec)
5789{
5790 unsigned int present;
5791
5792 present = snd_hda_codec_read(codec, 0x14, 0,
5793 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5794 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5795 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5796 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5797 present ? 1 : 3);
272a527c
KY
5798}
5799
5800static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5801{
5802 /* Looks like the unsol event is incompatible with the standard
5803 * definition. 4bit tag is placed at 26 bit!
5804 */
5805 if (((res >> 26) == ALC880_HP_EVENT)) {
5806 alc882_targa_automute(codec);
5807 }
5808}
5809
5810static struct hda_verb alc882_asus_a7j_verbs[] = {
5811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5813
5814 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5816 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5817
5818 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5819 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5820 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5821
5822 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5823 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5824 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5825 { } /* end */
5826};
5827
914759b7
TI
5828static struct hda_verb alc882_asus_a7m_verbs[] = {
5829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5831
5832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5833 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5835
5836 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5837 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5838 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5839
5840 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5841 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5842 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5843 { } /* end */
5844};
5845
9102cd1c
TD
5846static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5847{
5848 unsigned int gpiostate, gpiomask, gpiodir;
5849
5850 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5851 AC_VERB_GET_GPIO_DATA, 0);
5852
5853 if (!muted)
5854 gpiostate |= (1 << pin);
5855 else
5856 gpiostate &= ~(1 << pin);
5857
5858 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5859 AC_VERB_GET_GPIO_MASK, 0);
5860 gpiomask |= (1 << pin);
5861
5862 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5863 AC_VERB_GET_GPIO_DIRECTION, 0);
5864 gpiodir |= (1 << pin);
5865
5866
5867 snd_hda_codec_write(codec, codec->afg, 0,
5868 AC_VERB_SET_GPIO_MASK, gpiomask);
5869 snd_hda_codec_write(codec, codec->afg, 0,
5870 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5871
5872 msleep(1);
5873
5874 snd_hda_codec_write(codec, codec->afg, 0,
5875 AC_VERB_SET_GPIO_DATA, gpiostate);
5876}
5877
7debbe51
TI
5878/* set up GPIO at initialization */
5879static void alc885_macpro_init_hook(struct hda_codec *codec)
5880{
5881 alc882_gpio_mute(codec, 0, 0);
5882 alc882_gpio_mute(codec, 1, 0);
5883}
5884
5885/* set up GPIO and update auto-muting at initialization */
5886static void alc885_imac24_init_hook(struct hda_codec *codec)
5887{
5888 alc885_macpro_init_hook(codec);
5889 alc885_imac24_automute(codec);
5890}
5891
df694daa
KY
5892/*
5893 * generic initialization of ADC, input mixers and output mixers
5894 */
5895static struct hda_verb alc882_auto_init_verbs[] = {
5896 /*
5897 * Unmute ADC0-2 and set the default input to mic-in
5898 */
5899 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5900 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5901 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5903 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 5905
cb53c626 5906 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 5907 * mixer widget
f12ab1e0
TI
5908 * Note: PASD motherboards uses the Line In 2 as the input for
5909 * front panel mic (mic 2)
df694daa
KY
5910 */
5911 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5912 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5913 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5914 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5915 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5916 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 5917
df694daa
KY
5918 /*
5919 * Set up output mixers (0x0c - 0x0f)
5920 */
5921 /* set vol=0 to output mixers */
5922 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5923 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5924 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5925 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5926 /* set up input amps for analog loopback */
5927 /* Amp Indices: DAC = 0, mixer = 1 */
5928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5930 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5931 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5932 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5933 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5934 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5935 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5936 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5937 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5938
5939 /* FIXME: use matrix-type input source selection */
5940 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5941 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5943 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5944 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5945 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5946 /* Input mixer2 */
5947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5950 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5951 /* Input mixer3 */
5952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5956
5957 { }
5958};
5959
5960/* capture mixer elements */
5961static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5962 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5963 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5964 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5965 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5966 {
5967 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5968 /* The multiple "Capture Source" controls confuse alsamixer
5969 * So call somewhat different..
df694daa
KY
5970 */
5971 /* .name = "Capture Source", */
5972 .name = "Input Source",
5973 .count = 2,
5974 .info = alc882_mux_enum_info,
5975 .get = alc882_mux_enum_get,
5976 .put = alc882_mux_enum_put,
5977 },
5978 { } /* end */
5979};
5980
5981static struct snd_kcontrol_new alc882_capture_mixer[] = {
5982 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5983 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5984 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5985 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5986 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5987 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5988 {
5989 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5990 /* The multiple "Capture Source" controls confuse alsamixer
5991 * So call somewhat different..
df694daa
KY
5992 */
5993 /* .name = "Capture Source", */
5994 .name = "Input Source",
5995 .count = 3,
5996 .info = alc882_mux_enum_info,
5997 .get = alc882_mux_enum_get,
5998 .put = alc882_mux_enum_put,
5999 },
6000 { } /* end */
6001};
6002
cb53c626
TI
6003#ifdef CONFIG_SND_HDA_POWER_SAVE
6004#define alc882_loopbacks alc880_loopbacks
6005#endif
6006
df694daa
KY
6007/* pcm configuration: identiacal with ALC880 */
6008#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6009#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6010#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6011#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6012
6013/*
6014 * configuration and preset
6015 */
f5fcc13c
TI
6016static const char *alc882_models[ALC882_MODEL_LAST] = {
6017 [ALC882_3ST_DIG] = "3stack-dig",
6018 [ALC882_6ST_DIG] = "6stack-dig",
6019 [ALC882_ARIMA] = "arima",
bdd148a3 6020 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6021 [ALC882_TARGA] = "targa",
6022 [ALC882_ASUS_A7J] = "asus-a7j",
6023 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6024 [ALC885_MACPRO] = "macpro",
87350ad0 6025 [ALC885_MBP3] = "mbp3",
c54728d8 6026 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6027 [ALC882_AUTO] = "auto",
6028};
6029
6030static struct snd_pci_quirk alc882_cfg_tbl[] = {
6031 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6032 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6033 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6034 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6035 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6036 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6037 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6038 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6039 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6040 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6041 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6042 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6043 {}
6044};
6045
6046static struct alc_config_preset alc882_presets[] = {
6047 [ALC882_3ST_DIG] = {
6048 .mixers = { alc882_base_mixer },
6049 .init_verbs = { alc882_init_verbs },
6050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6051 .dac_nids = alc882_dac_nids,
6052 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6053 .dig_in_nid = ALC882_DIGIN_NID,
6054 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6055 .channel_mode = alc882_ch_modes,
4e195a7b 6056 .need_dac_fix = 1,
df694daa
KY
6057 .input_mux = &alc882_capture_source,
6058 },
6059 [ALC882_6ST_DIG] = {
6060 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6061 .init_verbs = { alc882_init_verbs },
6062 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6063 .dac_nids = alc882_dac_nids,
6064 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6065 .dig_in_nid = ALC882_DIGIN_NID,
6066 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6067 .channel_mode = alc882_sixstack_modes,
6068 .input_mux = &alc882_capture_source,
6069 },
4b146cb0
TI
6070 [ALC882_ARIMA] = {
6071 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6072 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6073 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6074 .dac_nids = alc882_dac_nids,
6075 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6076 .channel_mode = alc882_sixstack_modes,
6077 .input_mux = &alc882_capture_source,
6078 },
bdd148a3
KY
6079 [ALC882_W2JC] = {
6080 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6081 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6082 alc880_gpio1_init_verbs },
6083 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6084 .dac_nids = alc882_dac_nids,
6085 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6086 .channel_mode = alc880_threestack_modes,
6087 .need_dac_fix = 1,
6088 .input_mux = &alc882_capture_source,
6089 .dig_out_nid = ALC882_DIGOUT_NID,
6090 },
87350ad0
TI
6091 [ALC885_MBP3] = {
6092 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6093 .init_verbs = { alc885_mbp3_init_verbs,
6094 alc880_gpio1_init_verbs },
6095 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6096 .dac_nids = alc882_dac_nids,
6097 .channel_mode = alc885_mbp_6ch_modes,
6098 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6099 .input_mux = &alc882_capture_source,
6100 .dig_out_nid = ALC882_DIGOUT_NID,
6101 .dig_in_nid = ALC882_DIGIN_NID,
6102 .unsol_event = alc885_mbp3_unsol_event,
6103 .init_hook = alc885_mbp3_automute,
6104 },
9102cd1c
TD
6105 [ALC885_MACPRO] = {
6106 .mixers = { alc882_macpro_mixer },
6107 .init_verbs = { alc882_macpro_init_verbs },
6108 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6109 .dac_nids = alc882_dac_nids,
6110 .dig_out_nid = ALC882_DIGOUT_NID,
6111 .dig_in_nid = ALC882_DIGIN_NID,
6112 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6113 .channel_mode = alc882_ch_modes,
6114 .input_mux = &alc882_capture_source,
7debbe51 6115 .init_hook = alc885_macpro_init_hook,
9102cd1c 6116 },
c54728d8
NF
6117 [ALC885_IMAC24] = {
6118 .mixers = { alc885_imac24_mixer },
6119 .init_verbs = { alc885_imac24_init_verbs },
6120 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6121 .dac_nids = alc882_dac_nids,
6122 .dig_out_nid = ALC882_DIGOUT_NID,
6123 .dig_in_nid = ALC882_DIGIN_NID,
6124 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6125 .channel_mode = alc882_ch_modes,
6126 .input_mux = &alc882_capture_source,
6127 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6128 .init_hook = alc885_imac24_init_hook,
c54728d8 6129 },
272a527c
KY
6130 [ALC882_TARGA] = {
6131 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6132 alc882_capture_mixer },
6133 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6134 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6135 .dac_nids = alc882_dac_nids,
6136 .dig_out_nid = ALC882_DIGOUT_NID,
6137 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6138 .adc_nids = alc882_adc_nids,
e1406348 6139 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6140 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6141 .channel_mode = alc882_3ST_6ch_modes,
6142 .need_dac_fix = 1,
6143 .input_mux = &alc882_capture_source,
6144 .unsol_event = alc882_targa_unsol_event,
6145 .init_hook = alc882_targa_automute,
6146 },
6147 [ALC882_ASUS_A7J] = {
6148 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6149 alc882_capture_mixer },
6150 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6151 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6152 .dac_nids = alc882_dac_nids,
6153 .dig_out_nid = ALC882_DIGOUT_NID,
6154 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6155 .adc_nids = alc882_adc_nids,
e1406348 6156 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6157 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6158 .channel_mode = alc882_3ST_6ch_modes,
6159 .need_dac_fix = 1,
6160 .input_mux = &alc882_capture_source,
6161 },
914759b7
TI
6162 [ALC882_ASUS_A7M] = {
6163 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6164 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6165 alc880_gpio1_init_verbs,
6166 alc882_asus_a7m_verbs },
6167 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6168 .dac_nids = alc882_dac_nids,
6169 .dig_out_nid = ALC882_DIGOUT_NID,
6170 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6171 .channel_mode = alc880_threestack_modes,
6172 .need_dac_fix = 1,
6173 .input_mux = &alc882_capture_source,
6174 },
df694daa
KY
6175};
6176
6177
f95474ec
TI
6178/*
6179 * Pin config fixes
6180 */
6181enum {
6182 PINFIX_ABIT_AW9D_MAX
6183};
6184
6185static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6186 { 0x15, 0x01080104 }, /* side */
6187 { 0x16, 0x01011012 }, /* rear */
6188 { 0x17, 0x01016011 }, /* clfe */
6189 { }
6190};
6191
6192static const struct alc_pincfg *alc882_pin_fixes[] = {
6193 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6194};
6195
6196static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6197 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6198 {}
6199};
6200
df694daa
KY
6201/*
6202 * BIOS auto configuration
6203 */
6204static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6205 hda_nid_t nid, int pin_type,
6206 int dac_idx)
6207{
6208 /* set as output */
6209 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6210 int idx;
6211
f6c7e546 6212 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6213 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6214 idx = 4;
6215 else
6216 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6217 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6218
6219}
6220
6221static void alc882_auto_init_multi_out(struct hda_codec *codec)
6222{
6223 struct alc_spec *spec = codec->spec;
6224 int i;
6225
bc9f98a9 6226 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6227 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6228 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6229 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6230 if (nid)
baba8ee9 6231 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6232 i);
df694daa
KY
6233 }
6234}
6235
6236static void alc882_auto_init_hp_out(struct hda_codec *codec)
6237{
6238 struct alc_spec *spec = codec->spec;
6239 hda_nid_t pin;
6240
eb06ed8f 6241 pin = spec->autocfg.hp_pins[0];
df694daa 6242 if (pin) /* connect to front */
f12ab1e0
TI
6243 /* use dac 0 */
6244 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6245 pin = spec->autocfg.speaker_pins[0];
6246 if (pin)
6247 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6248}
6249
6250#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6251#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6252
6253static void alc882_auto_init_analog_input(struct hda_codec *codec)
6254{
6255 struct alc_spec *spec = codec->spec;
6256 int i;
6257
6258 for (i = 0; i < AUTO_PIN_LAST; i++) {
6259 hda_nid_t nid = spec->autocfg.input_pins[i];
6260 if (alc882_is_input_pin(nid)) {
f12ab1e0
TI
6261 snd_hda_codec_write(codec, nid, 0,
6262 AC_VERB_SET_PIN_WIDGET_CONTROL,
6263 i <= AUTO_PIN_FRONT_MIC ?
6264 PIN_VREF80 : PIN_IN);
df694daa 6265 if (nid != ALC882_PIN_CD_NID)
f12ab1e0
TI
6266 snd_hda_codec_write(codec, nid, 0,
6267 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6268 AMP_OUT_MUTE);
6269 }
6270 }
6271}
6272
776e184e
TI
6273/* add mic boosts if needed */
6274static int alc_auto_add_mic_boost(struct hda_codec *codec)
6275{
6276 struct alc_spec *spec = codec->spec;
6277 int err;
6278 hda_nid_t nid;
6279
6280 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6281 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6282 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6283 "Mic Boost",
6284 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6285 if (err < 0)
6286 return err;
6287 }
6288 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6289 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6290 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6291 "Front Mic Boost",
6292 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6293 if (err < 0)
6294 return err;
6295 }
6296 return 0;
6297}
6298
df694daa
KY
6299/* almost identical with ALC880 parser... */
6300static int alc882_parse_auto_config(struct hda_codec *codec)
6301{
6302 struct alc_spec *spec = codec->spec;
6303 int err = alc880_parse_auto_config(codec);
6304
6305 if (err < 0)
6306 return err;
776e184e
TI
6307 else if (!err)
6308 return 0; /* no config found */
6309
6310 err = alc_auto_add_mic_boost(codec);
6311 if (err < 0)
6312 return err;
6313
6314 /* hack - override the init verbs */
6315 spec->init_verbs[0] = alc882_auto_init_verbs;
6316
6317 return 1; /* config found */
df694daa
KY
6318}
6319
ae6b813a
TI
6320/* additional initialization for auto-configuration model */
6321static void alc882_auto_init(struct hda_codec *codec)
df694daa 6322{
f6c7e546 6323 struct alc_spec *spec = codec->spec;
df694daa
KY
6324 alc882_auto_init_multi_out(codec);
6325 alc882_auto_init_hp_out(codec);
6326 alc882_auto_init_analog_input(codec);
f6c7e546
TI
6327 if (spec->unsol_event)
6328 alc_sku_automute(codec);
df694daa
KY
6329}
6330
df694daa
KY
6331static int patch_alc882(struct hda_codec *codec)
6332{
6333 struct alc_spec *spec;
6334 int err, board_config;
6335
6336 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6337 if (spec == NULL)
6338 return -ENOMEM;
6339
6340 codec->spec = spec;
6341
f5fcc13c
TI
6342 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6343 alc882_models,
6344 alc882_cfg_tbl);
df694daa
KY
6345
6346 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6347 /* Pick up systems that don't supply PCI SSID */
6348 switch (codec->subsystem_id) {
6349 case 0x106b0c00: /* Mac Pro */
6350 board_config = ALC885_MACPRO;
6351 break;
c54728d8
NF
6352 case 0x106b1000: /* iMac 24 */
6353 board_config = ALC885_IMAC24;
6354 break;
3d5fa2e5 6355 case 0x106b00a1: /* Macbook */
87350ad0
TI
6356 case 0x106b2c00: /* Macbook Pro rev3 */
6357 board_config = ALC885_MBP3;
6358 break;
081d17c4
TD
6359 default:
6360 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6361 "trying auto-probe from BIOS...\n");
6362 board_config = ALC882_AUTO;
6363 }
df694daa
KY
6364 }
6365
f95474ec
TI
6366 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6367
df694daa
KY
6368 if (board_config == ALC882_AUTO) {
6369 /* automatic parse from the BIOS config */
6370 err = alc882_parse_auto_config(codec);
6371 if (err < 0) {
6372 alc_free(codec);
6373 return err;
f12ab1e0 6374 } else if (!err) {
9c7f852e
TI
6375 printk(KERN_INFO
6376 "hda_codec: Cannot set up configuration "
6377 "from BIOS. Using base mode...\n");
df694daa
KY
6378 board_config = ALC882_3ST_DIG;
6379 }
6380 }
6381
6382 if (board_config != ALC882_AUTO)
6383 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6384
6385 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6386 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6387 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6388 /* FIXME: setup DAC5 */
6389 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6390 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
6391
6392 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6393 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6394 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6395
f12ab1e0 6396 if (!spec->adc_nids && spec->input_mux) {
df694daa 6397 /* check whether NID 0x07 is valid */
4a471b7d 6398 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6399 /* get type */
6400 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6401 if (wcap != AC_WID_AUD_IN) {
6402 spec->adc_nids = alc882_adc_nids_alt;
6403 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6404 spec->capsrc_nids = alc882_capsrc_nids_alt;
f12ab1e0
TI
6405 spec->mixers[spec->num_mixers] =
6406 alc882_capture_alt_mixer;
df694daa
KY
6407 spec->num_mixers++;
6408 } else {
6409 spec->adc_nids = alc882_adc_nids;
6410 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6411 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
6412 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6413 spec->num_mixers++;
6414 }
6415 }
1da177e4 6416
2134ea4f
TI
6417 spec->vmaster_nid = 0x0c;
6418
1da177e4 6419 codec->patch_ops = alc_patch_ops;
df694daa 6420 if (board_config == ALC882_AUTO)
ae6b813a 6421 spec->init_hook = alc882_auto_init;
cb53c626
TI
6422#ifdef CONFIG_SND_HDA_POWER_SAVE
6423 if (!spec->loopback.amplist)
6424 spec->loopback.amplist = alc882_loopbacks;
6425#endif
df694daa
KY
6426
6427 return 0;
6428}
6429
6430/*
9c7f852e
TI
6431 * ALC883 support
6432 *
6433 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6434 * configuration. Each pin widget can choose any input DACs and a mixer.
6435 * Each ADC is connected from a mixer of all inputs. This makes possible
6436 * 6-channel independent captures.
6437 *
6438 * In addition, an independent DAC for the multi-playback (not used in this
6439 * driver yet).
df694daa 6440 */
9c7f852e
TI
6441#define ALC883_DIGOUT_NID 0x06
6442#define ALC883_DIGIN_NID 0x0a
df694daa 6443
9c7f852e
TI
6444static hda_nid_t alc883_dac_nids[4] = {
6445 /* front, rear, clfe, rear_surr */
6446 0x02, 0x04, 0x03, 0x05
6447};
df694daa 6448
9c7f852e
TI
6449static hda_nid_t alc883_adc_nids[2] = {
6450 /* ADC1-2 */
6451 0x08, 0x09,
6452};
f12ab1e0 6453
e1406348
TI
6454static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6455
9c7f852e
TI
6456/* input MUX */
6457/* FIXME: should be a matrix-type input source selection */
df694daa 6458
9c7f852e
TI
6459static struct hda_input_mux alc883_capture_source = {
6460 .num_items = 4,
6461 .items = {
6462 { "Mic", 0x0 },
6463 { "Front Mic", 0x1 },
6464 { "Line", 0x2 },
6465 { "CD", 0x4 },
6466 },
6467};
bc9f98a9
KY
6468
6469static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6470 .num_items = 2,
6471 .items = {
6472 { "Mic", 0x1 },
6473 { "Line", 0x2 },
6474 },
6475};
6476
272a527c
KY
6477static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6478 .num_items = 4,
6479 .items = {
6480 { "Mic", 0x0 },
6481 { "iMic", 0x1 },
6482 { "Line", 0x2 },
6483 { "CD", 0x4 },
6484 },
6485};
6486
9c7f852e
TI
6487#define alc883_mux_enum_info alc_mux_enum_info
6488#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6489/* ALC883 has the ALC882-type input selection */
6490#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6491
9c7f852e
TI
6492/*
6493 * 2ch mode
6494 */
6495static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6496 { 2, NULL }
6497};
6498
6499/*
6500 * 2ch mode
6501 */
6502static struct hda_verb alc883_3ST_ch2_init[] = {
6503 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6504 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6505 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6506 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6507 { } /* end */
6508};
6509
b201131c
TD
6510/*
6511 * 4ch mode
6512 */
6513static struct hda_verb alc883_3ST_ch4_init[] = {
6514 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6515 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6517 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6518 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6519 { } /* end */
6520};
6521
9c7f852e
TI
6522/*
6523 * 6ch mode
6524 */
6525static struct hda_verb alc883_3ST_ch6_init[] = {
6526 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6527 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6528 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6529 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6530 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6531 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6532 { } /* end */
6533};
6534
b201131c 6535static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6536 { 2, alc883_3ST_ch2_init },
b201131c 6537 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6538 { 6, alc883_3ST_ch6_init },
6539};
6540
6541/*
6542 * 6ch mode
6543 */
6544static struct hda_verb alc883_sixstack_ch6_init[] = {
6545 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6546 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6547 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6548 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6549 { } /* end */
6550};
6551
6552/*
6553 * 8ch mode
6554 */
6555static struct hda_verb alc883_sixstack_ch8_init[] = {
6556 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6557 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6558 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6559 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6560 { } /* end */
6561};
6562
6563static struct hda_channel_mode alc883_sixstack_modes[2] = {
6564 { 6, alc883_sixstack_ch6_init },
6565 { 8, alc883_sixstack_ch8_init },
6566};
6567
b373bdeb
AN
6568static struct hda_verb alc883_medion_eapd_verbs[] = {
6569 /* eanable EAPD on medion laptop */
6570 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6571 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6572 { }
6573};
6574
9c7f852e
TI
6575/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6576 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6577 */
6578
6579static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6583 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6588 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6589 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6598 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6599 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6601 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6602 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6603 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6604 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6605 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6606 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6607 {
6608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6609 /* .name = "Capture Source", */
6610 .name = "Input Source",
6611 .count = 2,
6612 .info = alc883_mux_enum_info,
6613 .get = alc883_mux_enum_get,
6614 .put = alc883_mux_enum_put,
6615 },
df694daa 6616 { } /* end */
834be88d
TI
6617};
6618
a8848bd6
AS
6619static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6620 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6621 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6622 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6623 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6624 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6625 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6628 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6631 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6632 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6633 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6634 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6635 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6636 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6637 {
6638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6639 /* .name = "Capture Source", */
6640 .name = "Input Source",
6641 .count = 2,
6642 .info = alc883_mux_enum_info,
6643 .get = alc883_mux_enum_get,
6644 .put = alc883_mux_enum_put,
6645 },
6646 { } /* end */
6647};
6648
368c7a95
J
6649static struct snd_kcontrol_new alc883_clevo_m720r_mixer[] = {
6650 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6651 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6652 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6653 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6655 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6657 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6658 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6659 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6660 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6661 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6662 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6663 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6664 {
6665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6666 /* .name = "Capture Source", */
6667 .name = "Input Source",
6668 .count = 2,
6669 .info = alc883_mux_enum_info,
6670 .get = alc883_mux_enum_get,
6671 .put = alc883_mux_enum_put,
6672 },
6673 { } /* end */
6674};
6675
9c7f852e
TI
6676static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6680 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6681 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6682 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6683 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6685 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6687 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6688 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6689 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6690 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6691 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6693 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6694 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6695 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6696 {
6697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6698 /* .name = "Capture Source", */
6699 .name = "Input Source",
6700 .count = 2,
6701 .info = alc883_mux_enum_info,
6702 .get = alc883_mux_enum_get,
6703 .put = alc883_mux_enum_put,
6704 },
6705 { } /* end */
6706};
df694daa 6707
9c7f852e
TI
6708static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6710 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6711 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6712 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6713 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6714 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6715 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6716 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6717 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6719 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6720 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6721 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6722 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6723 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6725 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6726 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6727 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6728 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6729 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6731 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6732 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6733 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6734 {
6735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6736 /* .name = "Capture Source", */
6737 .name = "Input Source",
6738 .count = 2,
6739 .info = alc883_mux_enum_info,
6740 .get = alc883_mux_enum_get,
6741 .put = alc883_mux_enum_put,
6742 },
6743 { } /* end */
6744};
6745
d1d985f0 6746static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6748 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6749 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6750 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6751 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6752 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6753 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6754 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6758 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6759 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6763 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6764 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6765 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6766 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6767 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6768 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6769 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6770
6771 {
6772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6773 /* .name = "Capture Source", */
6774 .name = "Input Source",
6775 .count = 1,
6776 .info = alc883_mux_enum_info,
6777 .get = alc883_mux_enum_get,
6778 .put = alc883_mux_enum_put,
6779 },
6780 { } /* end */
6781};
6782
ccc656ce
KY
6783static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6784 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6786 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6787 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6788 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6789 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6790 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6791 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6792 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6793 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6794 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6795 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6796 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6798 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6799 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6800 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6801 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6802 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6803 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6804 {
6805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6806 /* .name = "Capture Source", */
6807 .name = "Input Source",
6808 .count = 2,
6809 .info = alc883_mux_enum_info,
6810 .get = alc883_mux_enum_get,
6811 .put = alc883_mux_enum_put,
6812 },
6813 { } /* end */
f12ab1e0 6814};
ccc656ce
KY
6815
6816static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6817 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6819 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6820 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6821 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6822 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6823 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6825 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6826 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6827 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6828 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6829 {
6830 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6831 /* .name = "Capture Source", */
6832 .name = "Input Source",
6833 .count = 2,
6834 .info = alc883_mux_enum_info,
6835 .get = alc883_mux_enum_get,
6836 .put = alc883_mux_enum_put,
6837 },
6838 { } /* end */
f12ab1e0 6839};
ccc656ce 6840
bc9f98a9
KY
6841static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6842 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6843 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
6844 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6845 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
6846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6848 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6850 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6851 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6852 {
6853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6854 /* .name = "Capture Source", */
6855 .name = "Input Source",
6856 .count = 1,
6857 .info = alc883_mux_enum_info,
6858 .get = alc883_mux_enum_get,
6859 .put = alc883_mux_enum_put,
6860 },
6861 { } /* end */
f12ab1e0 6862};
bc9f98a9 6863
272a527c
KY
6864static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6865 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6866 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6871 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6872 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6873 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6874 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6875 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6876 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6877 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6878 {
6879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6880 /* .name = "Capture Source", */
6881 .name = "Input Source",
6882 .count = 2,
6883 .info = alc883_mux_enum_info,
6884 .get = alc883_mux_enum_get,
6885 .put = alc883_mux_enum_put,
6886 },
6887 { } /* end */
6888};
6889
6890static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6891 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6892 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6893 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6898 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6899 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6900 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6901 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6902 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6903 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6904 {
6905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6906 /* .name = "Capture Source", */
6907 .name = "Input Source",
6908 .count = 2,
6909 .info = alc883_mux_enum_info,
6910 .get = alc883_mux_enum_get,
6911 .put = alc883_mux_enum_put,
6912 },
6913 { } /* end */
6914};
6915
4723c022 6916static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
cd1e3b40
CM
6917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6918 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6919 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6920 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6921 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6922 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6923 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6924 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6925 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6926 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6928 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6929 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6930 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6931 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6933 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6936 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6937 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6938 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6939 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6940 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6941 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6942 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6943 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6944 {
6945 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6946 /* .name = "Capture Source", */
6947 .name = "Input Source",
6948 .count = 2,
6949 .info = alc883_mux_enum_info,
6950 .get = alc883_mux_enum_get,
6951 .put = alc883_mux_enum_put,
6952 },
6953 { } /* end */
6954};
6955
4723c022 6956static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
8341de60
CM
6957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6960 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6965 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6966 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6967 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6968 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6969 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6971 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6974 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6975 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6976 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6977 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6978 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6979 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6980 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6981 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6982 {
6983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6984 /* .name = "Capture Source", */
6985 .name = "Input Source",
6986 .count = 2,
6987 .info = alc883_mux_enum_info,
6988 .get = alc883_mux_enum_get,
6989 .put = alc883_mux_enum_put,
6990 },
6991 { } /* end */
6992};
6993
5795b9e6
CM
6994static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
6995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6996 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6997 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6998 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6999 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
7000 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7001 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7002 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7003 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7004 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7011 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7013 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7014 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7016 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7017 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7018 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7019 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7020 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7021 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7022 {
7023 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7024 /* .name = "Capture Source", */
7025 .name = "Input Source",
7026 .count = 2,
7027 .info = alc883_mux_enum_info,
7028 .get = alc883_mux_enum_get,
7029 .put = alc883_mux_enum_put,
7030 },
7031 { } /* end */
7032};
7033
2880a867 7034static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7035 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7036 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7039 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7041 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7043 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7044 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7045 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7046 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7047 {
7048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7049 /* .name = "Capture Source", */
7050 .name = "Input Source",
7051 .count = 2,
7052 .info = alc883_mux_enum_info,
7053 .get = alc883_mux_enum_get,
7054 .put = alc883_mux_enum_put,
7055 },
7056 { } /* end */
d1a991a6 7057};
2880a867 7058
9c7f852e
TI
7059static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7060 {
7061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7062 .name = "Channel Mode",
7063 .info = alc_ch_mode_info,
7064 .get = alc_ch_mode_get,
7065 .put = alc_ch_mode_put,
7066 },
7067 { } /* end */
7068};
7069
7070static struct hda_verb alc883_init_verbs[] = {
7071 /* ADC1: mute amp left and right */
7072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7073 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7074 /* ADC2: mute amp left and right */
7075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7076 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7077 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7081 /* Rear mixer */
7082 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7083 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7084 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7085 /* CLFE mixer */
7086 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7089 /* Side mixer */
7090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7093
cb53c626
TI
7094 /* mute analog input loopbacks */
7095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7100
9c7f852e
TI
7101 /* Front Pin: output 0 (0x0c) */
7102 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7103 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7104 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7105 /* Rear Pin: output 1 (0x0d) */
7106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7107 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7108 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7109 /* CLFE Pin: output 2 (0x0e) */
7110 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7112 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7113 /* Side Pin: output 3 (0x0f) */
7114 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7115 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7116 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7117 /* Mic (rear) pin: input vref at 80% */
7118 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7119 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7120 /* Front Mic pin: input vref at 80% */
7121 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7122 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7123 /* Line In pin: input */
7124 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7125 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7126 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7127 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7128 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7129 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7130 /* CD pin widget for input */
7131 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7132
7133 /* FIXME: use matrix-type input source selection */
7134 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7135 /* Input mixer2 */
7136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7140 /* Input mixer3 */
7141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7145 { }
7146};
7147
a8848bd6
AS
7148/* toggle speaker-output according to the hp-jack state */
7149static void alc883_mitac_hp_automute(struct hda_codec *codec)
7150{
7151 unsigned int present;
7152
7153 present = snd_hda_codec_read(codec, 0x15, 0,
7154 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7155 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7156 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7157 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7158 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7159}
7160
7161/* auto-toggle front mic */
7162/*
7163static void alc883_mitac_mic_automute(struct hda_codec *codec)
7164{
7165 unsigned int present;
7166 unsigned char bits;
7167
7168 present = snd_hda_codec_read(codec, 0x18, 0,
7169 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7170 bits = present ? HDA_AMP_MUTE : 0;
7171 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7172}
7173*/
7174
7175static void alc883_mitac_automute(struct hda_codec *codec)
7176{
7177 alc883_mitac_hp_automute(codec);
7178 /* alc883_mitac_mic_automute(codec); */
7179}
7180
7181static void alc883_mitac_unsol_event(struct hda_codec *codec,
7182 unsigned int res)
7183{
7184 switch (res >> 26) {
7185 case ALC880_HP_EVENT:
7186 alc883_mitac_hp_automute(codec);
7187 break;
7188 case ALC880_MIC_EVENT:
7189 /* alc883_mitac_mic_automute(codec); */
7190 break;
7191 }
7192}
7193
7194static struct hda_verb alc883_mitac_verbs[] = {
7195 /* HP */
7196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7197 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7198 /* Subwoofer */
7199 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7200 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7201
7202 /* enable unsolicited event */
7203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7204 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7205
7206 { } /* end */
7207};
7208
368c7a95
J
7209static struct hda_verb alc883_clevo_m720r_verbs[] = {
7210 /* HP */
7211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7212 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7213 /* Int speaker */
7214 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7215 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7216
7217 /* enable unsolicited event */
7218 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7219
7220 { } /* end */
7221};
7222
ccc656ce
KY
7223static struct hda_verb alc883_tagra_verbs[] = {
7224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7226
7227 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7229
7230 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7231 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7232 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7233
7234 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7235 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7236 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7237 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7238
7239 { } /* end */
7240};
7241
bc9f98a9
KY
7242static struct hda_verb alc883_lenovo_101e_verbs[] = {
7243 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7244 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7245 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7246 { } /* end */
7247};
7248
272a527c
KY
7249static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7250 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7251 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7252 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7253 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7254 { } /* end */
7255};
7256
7257static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7260 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7261 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7262 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7263 { } /* end */
7264};
7265
189609ae
KY
7266static struct hda_verb alc883_haier_w66_verbs[] = {
7267 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7268 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7269
7270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7271
7272 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7274 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7275 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7276 { } /* end */
7277};
7278
4723c022 7279static struct hda_verb alc888_6st_hp_verbs[] = {
cd1e3b40
CM
7280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7281 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
7282 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
7283 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7284 { }
7285};
7286
4723c022 7287static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60
CM
7288 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7289 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7290 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7291 { }
7292};
7293
5795b9e6
CM
7294static struct hda_verb alc888_6st_dell_verbs[] = {
7295 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7296 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
7297 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
7298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7299 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7300 { }
7301};
7302
4723c022 7303static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7304 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7305 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7306 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7307 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7308 { }
7309};
7310
4723c022 7311static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7314 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7315 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7316 { }
7317};
7318
4723c022
CM
7319static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7320 { 2, alc888_3st_hp_2ch_init },
7321 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7322};
7323
272a527c
KY
7324/* toggle front-jack and RCA according to the hp-jack state */
7325static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7326{
7327 unsigned int present;
7328
7329 present = snd_hda_codec_read(codec, 0x1b, 0,
7330 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7331 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7332 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7333 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7334 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7335}
7336
7337/* toggle RCA according to the front-jack state */
7338static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7339{
7340 unsigned int present;
7341
7342 present = snd_hda_codec_read(codec, 0x14, 0,
7343 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7344 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7345 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7346}
47fd830a 7347
272a527c
KY
7348static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7349 unsigned int res)
7350{
7351 if ((res >> 26) == ALC880_HP_EVENT)
7352 alc888_lenovo_ms7195_front_automute(codec);
7353 if ((res >> 26) == ALC880_FRONT_EVENT)
7354 alc888_lenovo_ms7195_rca_automute(codec);
7355}
7356
7357static struct hda_verb alc883_medion_md2_verbs[] = {
7358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7360
7361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7362
7363 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7364 { } /* end */
7365};
7366
7367/* toggle speaker-output according to the hp-jack state */
7368static void alc883_medion_md2_automute(struct hda_codec *codec)
7369{
7370 unsigned int present;
7371
7372 present = snd_hda_codec_read(codec, 0x14, 0,
7373 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7374 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7375 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7376}
7377
7378static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7379 unsigned int res)
7380{
7381 if ((res >> 26) == ALC880_HP_EVENT)
7382 alc883_medion_md2_automute(codec);
7383}
7384
ccc656ce
KY
7385/* toggle speaker-output according to the hp-jack state */
7386static void alc883_tagra_automute(struct hda_codec *codec)
7387{
7388 unsigned int present;
f12ab1e0 7389 unsigned char bits;
ccc656ce
KY
7390
7391 present = snd_hda_codec_read(codec, 0x14, 0,
7392 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7393 bits = present ? HDA_AMP_MUTE : 0;
7394 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7395 HDA_AMP_MUTE, bits);
82beb8fd
TI
7396 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7397 present ? 1 : 3);
ccc656ce
KY
7398}
7399
7400static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7401{
7402 if ((res >> 26) == ALC880_HP_EVENT)
7403 alc883_tagra_automute(codec);
7404}
7405
368c7a95
J
7406/* toggle speaker-output according to the hp-jack state */
7407static void alc883_clevo_m720r_automute(struct hda_codec *codec)
7408{
7409 unsigned int present;
7410 unsigned char bits;
7411
7412 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7413 & AC_PINSENSE_PRESENCE;
7414 bits = present ? HDA_AMP_MUTE : 0;
7415 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7416 HDA_AMP_MUTE, bits);
7417}
7418
7419static void alc883_clevo_m720r_unsol_event(struct hda_codec *codec,
7420 unsigned int res)
7421{
7422 if ((res >> 26) == ALC880_HP_EVENT)
7423 alc883_clevo_m720r_automute(codec);
7424}
7425
189609ae
KY
7426static void alc883_haier_w66_automute(struct hda_codec *codec)
7427{
7428 unsigned int present;
7429 unsigned char bits;
7430
7431 present = snd_hda_codec_read(codec, 0x1b, 0,
7432 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7433 bits = present ? 0x80 : 0;
7434 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7435 0x80, bits);
7436}
7437
7438static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7439 unsigned int res)
7440{
7441 if ((res >> 26) == ALC880_HP_EVENT)
7442 alc883_haier_w66_automute(codec);
7443}
7444
bc9f98a9
KY
7445static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7446{
7447 unsigned int present;
f12ab1e0 7448 unsigned char bits;
bc9f98a9
KY
7449
7450 present = snd_hda_codec_read(codec, 0x14, 0,
7451 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7452 bits = present ? HDA_AMP_MUTE : 0;
7453 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7454 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7455}
7456
7457static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7458{
7459 unsigned int present;
f12ab1e0 7460 unsigned char bits;
bc9f98a9
KY
7461
7462 present = snd_hda_codec_read(codec, 0x1b, 0,
7463 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7464 bits = present ? HDA_AMP_MUTE : 0;
7465 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7466 HDA_AMP_MUTE, bits);
7467 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7468 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7469}
7470
7471static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7472 unsigned int res)
7473{
7474 if ((res >> 26) == ALC880_HP_EVENT)
7475 alc883_lenovo_101e_all_automute(codec);
7476 if ((res >> 26) == ALC880_FRONT_EVENT)
7477 alc883_lenovo_101e_ispeaker_automute(codec);
7478}
7479
676a9b53
TI
7480/* toggle speaker-output according to the hp-jack state */
7481static void alc883_acer_aspire_automute(struct hda_codec *codec)
7482{
7483 unsigned int present;
7484
7485 present = snd_hda_codec_read(codec, 0x14, 0,
7486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7487 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7488 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7489 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7490 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7491}
7492
7493static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7494 unsigned int res)
7495{
7496 if ((res >> 26) == ALC880_HP_EVENT)
7497 alc883_acer_aspire_automute(codec);
7498}
7499
d1a991a6
KY
7500static struct hda_verb alc883_acer_eapd_verbs[] = {
7501 /* HP Pin: output 0 (0x0c) */
7502 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7503 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7504 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7505 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7507 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7508 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7509 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7510 /* eanable EAPD on medion laptop */
7511 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7512 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7513 /* enable unsolicited event */
7514 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7515 { }
7516};
7517
5795b9e6
CM
7518static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7519{
7520 unsigned int present;
7521
7522 present = snd_hda_codec_read(codec, 0x1b, 0,
7523 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7524 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7525 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7526 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7527 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7528 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7529 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7530 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7531 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7532}
7533
7534static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7535 unsigned int res)
7536{
7537 switch (res >> 26) {
7538 case ALC880_HP_EVENT:
7539 printk("hp_event\n");
7540 alc888_6st_dell_front_automute(codec);
7541 break;
7542 }
7543}
7544
9c7f852e
TI
7545/*
7546 * generic initialization of ADC, input mixers and output mixers
7547 */
7548static struct hda_verb alc883_auto_init_verbs[] = {
7549 /*
7550 * Unmute ADC0-2 and set the default input to mic-in
7551 */
7552 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7553 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7554 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7556
cb53c626 7557 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7558 * mixer widget
f12ab1e0
TI
7559 * Note: PASD motherboards uses the Line In 2 as the input for
7560 * front panel mic (mic 2)
9c7f852e
TI
7561 */
7562 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7568
7569 /*
7570 * Set up output mixers (0x0c - 0x0f)
7571 */
7572 /* set vol=0 to output mixers */
7573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7576 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7577 /* set up input amps for analog loopback */
7578 /* Amp Indices: DAC = 0, mixer = 1 */
7579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7580 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7584 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7585 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7586 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7587 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7588 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7589
7590 /* FIXME: use matrix-type input source selection */
7591 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7592 /* Input mixer1 */
7593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7596 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7598 /* Input mixer2 */
7599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7602 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7603 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7604
7605 { }
7606};
7607
7608/* capture mixer elements */
7609static struct snd_kcontrol_new alc883_capture_mixer[] = {
7610 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7611 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7612 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7613 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7614 {
7615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7616 /* The multiple "Capture Source" controls confuse alsamixer
7617 * So call somewhat different..
9c7f852e
TI
7618 */
7619 /* .name = "Capture Source", */
7620 .name = "Input Source",
7621 .count = 2,
7622 .info = alc882_mux_enum_info,
7623 .get = alc882_mux_enum_get,
7624 .put = alc882_mux_enum_put,
7625 },
7626 { } /* end */
7627};
7628
cb53c626
TI
7629#ifdef CONFIG_SND_HDA_POWER_SAVE
7630#define alc883_loopbacks alc880_loopbacks
7631#endif
7632
9c7f852e
TI
7633/* pcm configuration: identiacal with ALC880 */
7634#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7635#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 7636#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
7637#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7638#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7639
7640/*
7641 * configuration and preset
7642 */
f5fcc13c
TI
7643static const char *alc883_models[ALC883_MODEL_LAST] = {
7644 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7645 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7646 [ALC883_3ST_6ch] = "3stack-6ch",
7647 [ALC883_6ST_DIG] = "6stack-dig",
7648 [ALC883_TARGA_DIG] = "targa-dig",
7649 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7650 [ALC883_ACER] = "acer",
2880a867 7651 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7652 [ALC883_MEDION] = "medion",
272a527c 7653 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7654 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7655 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7656 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7657 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7658 [ALC883_HAIER_W66] = "haier-w66",
4723c022
CM
7659 [ALC888_6ST_HP] = "6stack-hp",
7660 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 7661 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 7662 [ALC883_MITAC] = "mitac",
368c7a95 7663 [ALC883_CLEVO_M720R] = "clevo-m720r",
f5fcc13c
TI
7664 [ALC883_AUTO] = "auto",
7665};
7666
7667static struct snd_pci_quirk alc883_cfg_tbl[] = {
7668 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7669 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7670 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7671 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7672 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 7673 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 7674 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7675 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7676 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7677 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7678 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
f5fcc13c 7679 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7680 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7681 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7682 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7683 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7684 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7685 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7686 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7687 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 7688 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 7689 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7690 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7691 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7692 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7693 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7694 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7695 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7696 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7697 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7698 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7699 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7700 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7701 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7702 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7703 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7704 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
368c7a95 7705 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720R),
ac3e3741 7706 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7707 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7708 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
272a527c 7709 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7710 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7711 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7712 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7713 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 7714 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 7715 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7716 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7717 {}
7718};
7719
7720static struct alc_config_preset alc883_presets[] = {
7721 [ALC883_3ST_2ch_DIG] = {
7722 .mixers = { alc883_3ST_2ch_mixer },
7723 .init_verbs = { alc883_init_verbs },
7724 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7725 .dac_nids = alc883_dac_nids,
7726 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7727 .dig_in_nid = ALC883_DIGIN_NID,
7728 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7729 .channel_mode = alc883_3ST_2ch_modes,
7730 .input_mux = &alc883_capture_source,
7731 },
7732 [ALC883_3ST_6ch_DIG] = {
7733 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7734 .init_verbs = { alc883_init_verbs },
7735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7736 .dac_nids = alc883_dac_nids,
7737 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7738 .dig_in_nid = ALC883_DIGIN_NID,
7739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7740 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7741 .need_dac_fix = 1,
9c7f852e 7742 .input_mux = &alc883_capture_source,
f12ab1e0 7743 },
9c7f852e
TI
7744 [ALC883_3ST_6ch] = {
7745 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7746 .init_verbs = { alc883_init_verbs },
7747 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7748 .dac_nids = alc883_dac_nids,
9c7f852e
TI
7749 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7750 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7751 .need_dac_fix = 1,
9c7f852e 7752 .input_mux = &alc883_capture_source,
f12ab1e0 7753 },
9c7f852e
TI
7754 [ALC883_6ST_DIG] = {
7755 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7756 .init_verbs = { alc883_init_verbs },
7757 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7758 .dac_nids = alc883_dac_nids,
7759 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7760 .dig_in_nid = ALC883_DIGIN_NID,
7761 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7762 .channel_mode = alc883_sixstack_modes,
7763 .input_mux = &alc883_capture_source,
7764 },
ccc656ce
KY
7765 [ALC883_TARGA_DIG] = {
7766 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7767 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7768 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7769 .dac_nids = alc883_dac_nids,
7770 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7771 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7772 .channel_mode = alc883_3ST_6ch_modes,
7773 .need_dac_fix = 1,
7774 .input_mux = &alc883_capture_source,
7775 .unsol_event = alc883_tagra_unsol_event,
7776 .init_hook = alc883_tagra_automute,
7777 },
7778 [ALC883_TARGA_2ch_DIG] = {
7779 .mixers = { alc883_tagra_2ch_mixer},
7780 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7781 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7782 .dac_nids = alc883_dac_nids,
7783 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7784 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7785 .channel_mode = alc883_3ST_2ch_modes,
7786 .input_mux = &alc883_capture_source,
7787 .unsol_event = alc883_tagra_unsol_event,
7788 .init_hook = alc883_tagra_automute,
7789 },
bab282b9 7790 [ALC883_ACER] = {
676a9b53 7791 .mixers = { alc883_base_mixer },
bab282b9
VA
7792 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7793 * and the headphone jack. Turn this on and rely on the
7794 * standard mute methods whenever the user wants to turn
7795 * these outputs off.
7796 */
7797 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7798 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7799 .dac_nids = alc883_dac_nids,
bab282b9
VA
7800 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7801 .channel_mode = alc883_3ST_2ch_modes,
7802 .input_mux = &alc883_capture_source,
7803 },
2880a867 7804 [ALC883_ACER_ASPIRE] = {
676a9b53 7805 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7806 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7807 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7808 .dac_nids = alc883_dac_nids,
7809 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
7810 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7811 .channel_mode = alc883_3ST_2ch_modes,
7812 .input_mux = &alc883_capture_source,
676a9b53
TI
7813 .unsol_event = alc883_acer_aspire_unsol_event,
7814 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7815 },
c07584c8
TD
7816 [ALC883_MEDION] = {
7817 .mixers = { alc883_fivestack_mixer,
7818 alc883_chmode_mixer },
7819 .init_verbs = { alc883_init_verbs,
b373bdeb 7820 alc883_medion_eapd_verbs },
c07584c8
TD
7821 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7822 .dac_nids = alc883_dac_nids,
c07584c8
TD
7823 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7824 .channel_mode = alc883_sixstack_modes,
7825 .input_mux = &alc883_capture_source,
b373bdeb 7826 },
272a527c
KY
7827 [ALC883_MEDION_MD2] = {
7828 .mixers = { alc883_medion_md2_mixer},
7829 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7831 .dac_nids = alc883_dac_nids,
7832 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7833 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7834 .channel_mode = alc883_3ST_2ch_modes,
7835 .input_mux = &alc883_capture_source,
7836 .unsol_event = alc883_medion_md2_unsol_event,
7837 .init_hook = alc883_medion_md2_automute,
7838 },
b373bdeb 7839 [ALC883_LAPTOP_EAPD] = {
676a9b53 7840 .mixers = { alc883_base_mixer },
b373bdeb
AN
7841 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7843 .dac_nids = alc883_dac_nids,
b373bdeb
AN
7844 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7845 .channel_mode = alc883_3ST_2ch_modes,
7846 .input_mux = &alc883_capture_source,
7847 },
368c7a95
J
7848 [ALC883_CLEVO_M720R] = {
7849 .mixers = { alc883_clevo_m720r_mixer },
7850 .init_verbs = { alc883_init_verbs, alc883_clevo_m720r_verbs },
7851 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7852 .dac_nids = alc883_dac_nids,
7853 .dig_out_nid = ALC883_DIGOUT_NID,
7854 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7855 .channel_mode = alc883_3ST_2ch_modes,
7856 .input_mux = &alc883_capture_source,
7857 .unsol_event = alc883_clevo_m720r_unsol_event,
7858 .init_hook = alc883_clevo_m720r_automute,
7859 },
bc9f98a9
KY
7860 [ALC883_LENOVO_101E_2ch] = {
7861 .mixers = { alc883_lenovo_101e_2ch_mixer},
7862 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7863 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7864 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
7865 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7866 .channel_mode = alc883_3ST_2ch_modes,
7867 .input_mux = &alc883_lenovo_101e_capture_source,
7868 .unsol_event = alc883_lenovo_101e_unsol_event,
7869 .init_hook = alc883_lenovo_101e_all_automute,
7870 },
272a527c
KY
7871 [ALC883_LENOVO_NB0763] = {
7872 .mixers = { alc883_lenovo_nb0763_mixer },
7873 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7874 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7875 .dac_nids = alc883_dac_nids,
272a527c
KY
7876 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7877 .channel_mode = alc883_3ST_2ch_modes,
7878 .need_dac_fix = 1,
7879 .input_mux = &alc883_lenovo_nb0763_capture_source,
7880 .unsol_event = alc883_medion_md2_unsol_event,
7881 .init_hook = alc883_medion_md2_automute,
7882 },
7883 [ALC888_LENOVO_MS7195_DIG] = {
7884 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7885 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7886 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7887 .dac_nids = alc883_dac_nids,
7888 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7889 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7890 .channel_mode = alc883_3ST_6ch_modes,
7891 .need_dac_fix = 1,
7892 .input_mux = &alc883_capture_source,
7893 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7894 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7895 },
7896 [ALC883_HAIER_W66] = {
7897 .mixers = { alc883_tagra_2ch_mixer},
7898 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7899 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7900 .dac_nids = alc883_dac_nids,
7901 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
7902 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7903 .channel_mode = alc883_3ST_2ch_modes,
7904 .input_mux = &alc883_capture_source,
7905 .unsol_event = alc883_haier_w66_unsol_event,
7906 .init_hook = alc883_haier_w66_automute,
272a527c 7907 },
4723c022
CM
7908 [ALC888_6ST_HP] = {
7909 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7910 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
cd1e3b40
CM
7911 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7912 .dac_nids = alc883_dac_nids,
7913 .dig_out_nid = ALC883_DIGOUT_NID,
cd1e3b40
CM
7914 .dig_in_nid = ALC883_DIGIN_NID,
7915 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7916 .channel_mode = alc883_sixstack_modes,
7917 .input_mux = &alc883_capture_source,
7918 },
4723c022
CM
7919 [ALC888_3ST_HP] = {
7920 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7921 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7922 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7923 .dac_nids = alc883_dac_nids,
4723c022
CM
7924 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7925 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7926 .need_dac_fix = 1,
7927 .input_mux = &alc883_capture_source,
7928 },
5795b9e6
CM
7929 [ALC888_6ST_DELL] = {
7930 .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
7931 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7932 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7933 .dac_nids = alc883_dac_nids,
7934 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
7935 .dig_in_nid = ALC883_DIGIN_NID,
7936 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7937 .channel_mode = alc883_sixstack_modes,
7938 .input_mux = &alc883_capture_source,
7939 .unsol_event = alc888_6st_dell_unsol_event,
7940 .init_hook = alc888_6st_dell_front_automute,
7941 },
a8848bd6
AS
7942 [ALC883_MITAC] = {
7943 .mixers = { alc883_mitac_mixer },
7944 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7945 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7946 .dac_nids = alc883_dac_nids,
a8848bd6
AS
7947 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7948 .channel_mode = alc883_3ST_2ch_modes,
7949 .input_mux = &alc883_capture_source,
7950 .unsol_event = alc883_mitac_unsol_event,
7951 .init_hook = alc883_mitac_automute,
7952 },
9c7f852e
TI
7953};
7954
7955
7956/*
7957 * BIOS auto configuration
7958 */
7959static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7960 hda_nid_t nid, int pin_type,
7961 int dac_idx)
7962{
7963 /* set as output */
7964 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7965 int idx;
7966
f6c7e546 7967 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
7968 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7969 idx = 4;
7970 else
7971 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
7972 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7973
7974}
7975
7976static void alc883_auto_init_multi_out(struct hda_codec *codec)
7977{
7978 struct alc_spec *spec = codec->spec;
7979 int i;
7980
bc9f98a9 7981 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 7982 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7983 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7984 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 7985 if (nid)
baba8ee9 7986 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7987 i);
9c7f852e
TI
7988 }
7989}
7990
7991static void alc883_auto_init_hp_out(struct hda_codec *codec)
7992{
7993 struct alc_spec *spec = codec->spec;
7994 hda_nid_t pin;
7995
eb06ed8f 7996 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
7997 if (pin) /* connect to front */
7998 /* use dac 0 */
7999 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
8000 pin = spec->autocfg.speaker_pins[0];
8001 if (pin)
8002 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
8003}
8004
8005#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8006#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8007
8008static void alc883_auto_init_analog_input(struct hda_codec *codec)
8009{
8010 struct alc_spec *spec = codec->spec;
8011 int i;
8012
8013 for (i = 0; i < AUTO_PIN_LAST; i++) {
8014 hda_nid_t nid = spec->autocfg.input_pins[i];
8015 if (alc883_is_input_pin(nid)) {
8016 snd_hda_codec_write(codec, nid, 0,
8017 AC_VERB_SET_PIN_WIDGET_CONTROL,
8018 (i <= AUTO_PIN_FRONT_MIC ?
8019 PIN_VREF80 : PIN_IN));
8020 if (nid != ALC883_PIN_CD_NID)
8021 snd_hda_codec_write(codec, nid, 0,
8022 AC_VERB_SET_AMP_GAIN_MUTE,
8023 AMP_OUT_MUTE);
8024 }
8025 }
8026}
8027
8028/* almost identical with ALC880 parser... */
8029static int alc883_parse_auto_config(struct hda_codec *codec)
8030{
8031 struct alc_spec *spec = codec->spec;
8032 int err = alc880_parse_auto_config(codec);
8033
8034 if (err < 0)
8035 return err;
776e184e
TI
8036 else if (!err)
8037 return 0; /* no config found */
8038
8039 err = alc_auto_add_mic_boost(codec);
8040 if (err < 0)
8041 return err;
8042
8043 /* hack - override the init verbs */
8044 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
8045 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8046 spec->num_mixers++;
776e184e
TI
8047
8048 return 1; /* config found */
9c7f852e
TI
8049}
8050
8051/* additional initialization for auto-configuration model */
8052static void alc883_auto_init(struct hda_codec *codec)
8053{
f6c7e546 8054 struct alc_spec *spec = codec->spec;
9c7f852e
TI
8055 alc883_auto_init_multi_out(codec);
8056 alc883_auto_init_hp_out(codec);
8057 alc883_auto_init_analog_input(codec);
f6c7e546
TI
8058 if (spec->unsol_event)
8059 alc_sku_automute(codec);
9c7f852e
TI
8060}
8061
8062static int patch_alc883(struct hda_codec *codec)
8063{
8064 struct alc_spec *spec;
8065 int err, board_config;
8066
8067 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8068 if (spec == NULL)
8069 return -ENOMEM;
8070
8071 codec->spec = spec;
8072
f5fcc13c
TI
8073 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8074 alc883_models,
8075 alc883_cfg_tbl);
8076 if (board_config < 0) {
9c7f852e
TI
8077 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8078 "trying auto-probe from BIOS...\n");
8079 board_config = ALC883_AUTO;
8080 }
8081
8082 if (board_config == ALC883_AUTO) {
8083 /* automatic parse from the BIOS config */
8084 err = alc883_parse_auto_config(codec);
8085 if (err < 0) {
8086 alc_free(codec);
8087 return err;
f12ab1e0 8088 } else if (!err) {
9c7f852e
TI
8089 printk(KERN_INFO
8090 "hda_codec: Cannot set up configuration "
8091 "from BIOS. Using base mode...\n");
8092 board_config = ALC883_3ST_2ch_DIG;
8093 }
8094 }
8095
8096 if (board_config != ALC883_AUTO)
8097 setup_preset(spec, &alc883_presets[board_config]);
8098
8099 spec->stream_name_analog = "ALC883 Analog";
8100 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8101 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8102 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e
TI
8103
8104 spec->stream_name_digital = "ALC883 Digital";
8105 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8106 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8107
e1406348
TI
8108 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8109 spec->adc_nids = alc883_adc_nids;
8110 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8111
2134ea4f
TI
8112 spec->vmaster_nid = 0x0c;
8113
9c7f852e
TI
8114 codec->patch_ops = alc_patch_ops;
8115 if (board_config == ALC883_AUTO)
8116 spec->init_hook = alc883_auto_init;
cb53c626
TI
8117#ifdef CONFIG_SND_HDA_POWER_SAVE
8118 if (!spec->loopback.amplist)
8119 spec->loopback.amplist = alc883_loopbacks;
8120#endif
9c7f852e
TI
8121
8122 return 0;
8123}
8124
8125/*
8126 * ALC262 support
8127 */
8128
8129#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8130#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8131
8132#define alc262_dac_nids alc260_dac_nids
8133#define alc262_adc_nids alc882_adc_nids
8134#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
8135#define alc262_capsrc_nids alc882_capsrc_nids
8136#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
8137
8138#define alc262_modes alc260_modes
8139#define alc262_capture_source alc882_capture_source
8140
8141static struct snd_kcontrol_new alc262_base_mixer[] = {
8142 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8143 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8150 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8151 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8153 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8154 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8155 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
8156 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8158 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8159 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8160 { } /* end */
8161};
8162
ccc656ce
KY
8163static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8165 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8166 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8167 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8168 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8169 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8172 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
8173 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8174 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8175 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 8176 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8177 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
8178 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8179 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8180 { } /* end */
8181};
8182
ce875f07
TI
8183/* update HP, line and mono-out pins according to the master switch */
8184static void alc262_hp_master_update(struct hda_codec *codec)
8185{
8186 struct alc_spec *spec = codec->spec;
8187 int val = spec->master_sw;
8188
8189 /* HP & line-out */
8190 snd_hda_codec_write_cache(codec, 0x1b, 0,
8191 AC_VERB_SET_PIN_WIDGET_CONTROL,
8192 val ? PIN_HP : 0);
8193 snd_hda_codec_write_cache(codec, 0x15, 0,
8194 AC_VERB_SET_PIN_WIDGET_CONTROL,
8195 val ? PIN_HP : 0);
8196 /* mono (speaker) depending on the HP jack sense */
8197 val = val && !spec->jack_present;
8198 snd_hda_codec_write_cache(codec, 0x16, 0,
8199 AC_VERB_SET_PIN_WIDGET_CONTROL,
8200 val ? PIN_OUT : 0);
8201}
8202
8203static void alc262_hp_bpc_automute(struct hda_codec *codec)
8204{
8205 struct alc_spec *spec = codec->spec;
8206 unsigned int presence;
8207 presence = snd_hda_codec_read(codec, 0x1b, 0,
8208 AC_VERB_GET_PIN_SENSE, 0);
8209 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8210 alc262_hp_master_update(codec);
8211}
8212
8213static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8214{
8215 if ((res >> 26) != ALC880_HP_EVENT)
8216 return;
8217 alc262_hp_bpc_automute(codec);
8218}
8219
8220static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8221{
8222 struct alc_spec *spec = codec->spec;
8223 unsigned int presence;
8224 presence = snd_hda_codec_read(codec, 0x15, 0,
8225 AC_VERB_GET_PIN_SENSE, 0);
8226 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8227 alc262_hp_master_update(codec);
8228}
8229
8230static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8231 unsigned int res)
8232{
8233 if ((res >> 26) != ALC880_HP_EVENT)
8234 return;
8235 alc262_hp_wildwest_automute(codec);
8236}
8237
8238static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8239 struct snd_ctl_elem_value *ucontrol)
8240{
8241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8242 struct alc_spec *spec = codec->spec;
8243 *ucontrol->value.integer.value = spec->master_sw;
8244 return 0;
8245}
8246
8247static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8248 struct snd_ctl_elem_value *ucontrol)
8249{
8250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8251 struct alc_spec *spec = codec->spec;
8252 int val = !!*ucontrol->value.integer.value;
8253
8254 if (val == spec->master_sw)
8255 return 0;
8256 spec->master_sw = val;
8257 alc262_hp_master_update(codec);
8258 return 1;
8259}
8260
9c7f852e 8261static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
8262 {
8263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8264 .name = "Master Playback Switch",
8265 .info = snd_ctl_boolean_mono_info,
8266 .get = alc262_hp_master_sw_get,
8267 .put = alc262_hp_master_sw_put,
8268 },
9c7f852e
TI
8269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8270 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8271 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
8272 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8273 HDA_OUTPUT),
8274 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8275 HDA_OUTPUT),
9c7f852e
TI
8276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8278 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8279 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8280 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8281 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
8282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8286 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8287 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8288 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8289 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8290 { } /* end */
8291};
8292
cd7509a4 8293static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
8294 {
8295 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8296 .name = "Master Playback Switch",
8297 .info = snd_ctl_boolean_mono_info,
8298 .get = alc262_hp_master_sw_get,
8299 .put = alc262_hp_master_sw_put,
8300 },
cd7509a4
KY
8301 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8302 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8303 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
8305 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8306 HDA_OUTPUT),
8307 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8308 HDA_OUTPUT),
cd7509a4
KY
8309 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8310 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 8311 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
8312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8314 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8315 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8316 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8317 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8318 { } /* end */
8319};
8320
8321static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8322 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8323 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8324 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
8325 { } /* end */
8326};
8327
66d2a9d6
KY
8328/* mute/unmute internal speaker according to the hp jack and mute state */
8329static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8330{
8331 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
8332
8333 if (force || !spec->sense_updated) {
8334 unsigned int present;
8335 present = snd_hda_codec_read(codec, 0x15, 0,
8336 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 8337 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
8338 spec->sense_updated = 1;
8339 }
4bb26130
TI
8340 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8341 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
8342}
8343
8344static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8345 unsigned int res)
8346{
8347 if ((res >> 26) != ALC880_HP_EVENT)
8348 return;
8349 alc262_hp_t5735_automute(codec, 1);
8350}
8351
8352static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8353{
8354 alc262_hp_t5735_automute(codec, 1);
8355}
8356
8357static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
8358 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8359 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
8360 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8363 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8364 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8365 { } /* end */
8366};
8367
8368static struct hda_verb alc262_hp_t5735_verbs[] = {
8369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8371
8372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8373 { }
8374};
8375
8c427226 8376static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
8377 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
8379 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8380 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
8381 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8382 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8383 { } /* end */
8384};
8385
8386static struct hda_verb alc262_hp_rp5700_verbs[] = {
8387 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8388 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8390 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8391 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8392 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8393 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8395 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8396 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8397 {}
8398};
8399
8400static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8401 .num_items = 1,
8402 .items = {
8403 { "Line", 0x1 },
8404 },
8405};
8406
0724ea2a
TI
8407/* bind hp and internal speaker mute (with plug check) */
8408static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8409 struct snd_ctl_elem_value *ucontrol)
8410{
8411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8412 long *valp = ucontrol->value.integer.value;
8413 int change;
8414
8415 /* change hp mute */
8416 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8417 HDA_AMP_MUTE,
8418 valp[0] ? 0 : HDA_AMP_MUTE);
8419 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8420 HDA_AMP_MUTE,
8421 valp[1] ? 0 : HDA_AMP_MUTE);
8422 if (change) {
8423 /* change speaker according to HP jack state */
8424 struct alc_spec *spec = codec->spec;
8425 unsigned int mute;
8426 if (spec->jack_present)
8427 mute = HDA_AMP_MUTE;
8428 else
8429 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8430 HDA_OUTPUT, 0);
8431 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8432 HDA_AMP_MUTE, mute);
8433 }
8434 return change;
8435}
5b31954e 8436
272a527c 8437static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
8438 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8439 {
8440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8441 .name = "Master Playback Switch",
8442 .info = snd_hda_mixer_amp_switch_info,
8443 .get = snd_hda_mixer_amp_switch_get,
8444 .put = alc262_sony_master_sw_put,
8445 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8446 },
272a527c
KY
8447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8449 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8450 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8451 { } /* end */
8452};
8453
83c34218
KY
8454static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8455 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8456 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8460 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8461 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8462 { } /* end */
8463};
272a527c 8464
9c7f852e
TI
8465#define alc262_capture_mixer alc882_capture_mixer
8466#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8467
8468/*
8469 * generic initialization of ADC, input mixers and output mixers
8470 */
8471static struct hda_verb alc262_init_verbs[] = {
8472 /*
8473 * Unmute ADC0-2 and set the default input to mic-in
8474 */
8475 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8476 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8477 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8479 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8480 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8481
cb53c626 8482 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8483 * mixer widget
f12ab1e0
TI
8484 * Note: PASD motherboards uses the Line In 2 as the input for
8485 * front panel mic (mic 2)
9c7f852e
TI
8486 */
8487 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8493
8494 /*
df694daa
KY
8495 * Set up output mixers (0x0c - 0x0e)
8496 */
8497 /* set vol=0 to output mixers */
8498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8499 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8500 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8501 /* set up input amps for analog loopback */
8502 /* Amp Indices: DAC = 0, mixer = 1 */
8503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8509
8510 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8512 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8514 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8515 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8516
8517 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8520 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8521 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8522
8523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8524 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8525
8526 /* FIXME: use matrix-type input source selection */
8527 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8528 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8532 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8533 /* Input mixer2 */
8534 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8536 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8538 /* Input mixer3 */
8539 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8540 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8543
8544 { }
8545};
1da177e4 8546
ccc656ce
KY
8547static struct hda_verb alc262_hippo_unsol_verbs[] = {
8548 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8549 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8550 {}
8551};
8552
8553static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8555 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8557
8558 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8560 {}
8561};
8562
272a527c
KY
8563static struct hda_verb alc262_sony_unsol_verbs[] = {
8564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8565 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8566 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8567
8568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570};
8571
ccc656ce 8572/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8573static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8574{
8575 struct alc_spec *spec = codec->spec;
8576 unsigned int mute;
5b31954e 8577 unsigned int present;
ccc656ce 8578
5b31954e
TI
8579 /* need to execute and sync at first */
8580 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8581 present = snd_hda_codec_read(codec, 0x15, 0,
8582 AC_VERB_GET_PIN_SENSE, 0);
8583 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8584 if (spec->jack_present) {
8585 /* mute internal speaker */
47fd830a
TI
8586 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8587 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8588 } else {
8589 /* unmute internal speaker if necessary */
8590 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8591 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8592 HDA_AMP_MUTE, mute);
ccc656ce
KY
8593 }
8594}
8595
8596/* unsolicited event for HP jack sensing */
8597static void alc262_hippo_unsol_event(struct hda_codec *codec,
8598 unsigned int res)
8599{
8600 if ((res >> 26) != ALC880_HP_EVENT)
8601 return;
5b31954e 8602 alc262_hippo_automute(codec);
ccc656ce
KY
8603}
8604
5b31954e 8605static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8606{
ccc656ce 8607 unsigned int mute;
5b31954e 8608 unsigned int present;
ccc656ce 8609
5b31954e
TI
8610 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8611 present = snd_hda_codec_read(codec, 0x1b, 0,
8612 AC_VERB_GET_PIN_SENSE, 0);
8613 present = (present & 0x80000000) != 0;
8614 if (present) {
ccc656ce 8615 /* mute internal speaker */
47fd830a
TI
8616 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8617 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8618 } else {
8619 /* unmute internal speaker if necessary */
8620 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8621 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8622 HDA_AMP_MUTE, mute);
ccc656ce
KY
8623 }
8624}
8625
8626/* unsolicited event for HP jack sensing */
8627static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8628 unsigned int res)
8629{
8630 if ((res >> 26) != ALC880_HP_EVENT)
8631 return;
5b31954e 8632 alc262_hippo1_automute(codec);
ccc656ce
KY
8633}
8634
834be88d
TI
8635/*
8636 * fujitsu model
8637 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8638 */
8639
8640#define ALC_HP_EVENT 0x37
8641
8642static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8645 {}
8646};
8647
8648static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8649 .num_items = 3,
834be88d
TI
8650 .items = {
8651 { "Mic", 0x0 },
39d3ed38 8652 { "Int Mic", 0x1 },
834be88d
TI
8653 { "CD", 0x4 },
8654 },
8655};
8656
9c7f852e
TI
8657static struct hda_input_mux alc262_HP_capture_source = {
8658 .num_items = 5,
8659 .items = {
8660 { "Mic", 0x0 },
accbe498 8661 { "Front Mic", 0x1 },
9c7f852e
TI
8662 { "Line", 0x2 },
8663 { "CD", 0x4 },
8664 { "AUX IN", 0x6 },
8665 },
8666};
8667
accbe498 8668static struct hda_input_mux alc262_HP_D7000_capture_source = {
8669 .num_items = 4,
8670 .items = {
8671 { "Mic", 0x0 },
8672 { "Front Mic", 0x2 },
8673 { "Line", 0x1 },
8674 { "CD", 0x4 },
8675 },
8676};
8677
834be88d
TI
8678/* mute/unmute internal speaker according to the hp jack and mute state */
8679static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8680{
8681 struct alc_spec *spec = codec->spec;
8682 unsigned int mute;
8683
f12ab1e0 8684 if (force || !spec->sense_updated) {
834be88d
TI
8685 unsigned int present;
8686 /* need to execute and sync at first */
8687 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8688 present = snd_hda_codec_read(codec, 0x14, 0,
8689 AC_VERB_GET_PIN_SENSE, 0);
8690 spec->jack_present = (present & 0x80000000) != 0;
8691 spec->sense_updated = 1;
8692 }
8693 if (spec->jack_present) {
8694 /* mute internal speaker */
47fd830a
TI
8695 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8696 HDA_AMP_MUTE, HDA_AMP_MUTE);
834be88d
TI
8697 } else {
8698 /* unmute internal speaker if necessary */
8699 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
47fd830a
TI
8700 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8701 HDA_AMP_MUTE, mute);
834be88d
TI
8702 }
8703}
8704
8705/* unsolicited event for HP jack sensing */
8706static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8707 unsigned int res)
8708{
8709 if ((res >> 26) != ALC_HP_EVENT)
8710 return;
8711 alc262_fujitsu_automute(codec, 1);
8712}
8713
8714/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8715static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8716 .ops = &snd_hda_bind_vol,
8717 .values = {
8718 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8719 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8720 0
8721 },
8722};
834be88d
TI
8723
8724/* bind hp and internal speaker mute (with plug check) */
8725static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8726 struct snd_ctl_elem_value *ucontrol)
8727{
8728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8729 long *valp = ucontrol->value.integer.value;
8730 int change;
8731
8732 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
47fd830a
TI
8733 HDA_AMP_MUTE,
8734 valp[0] ? 0 : HDA_AMP_MUTE);
834be88d 8735 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
47fd830a
TI
8736 HDA_AMP_MUTE,
8737 valp[1] ? 0 : HDA_AMP_MUTE);
82beb8fd
TI
8738 if (change)
8739 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8740 return change;
8741}
8742
8743static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8744 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8745 {
8746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8747 .name = "Master Playback Switch",
8748 .info = snd_hda_mixer_amp_switch_info,
8749 .get = snd_hda_mixer_amp_switch_get,
8750 .put = alc262_fujitsu_master_sw_put,
8751 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8752 },
8753 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8754 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8755 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8758 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8759 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8760 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8761 { } /* end */
8762};
8763
304dcaac
TI
8764/* additional init verbs for Benq laptops */
8765static struct hda_verb alc262_EAPD_verbs[] = {
8766 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8767 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8768 {}
8769};
8770
83c34218
KY
8771static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8772 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8774
8775 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8776 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8777 {}
8778};
8779
f651b50b
TD
8780/* Samsung Q1 Ultra Vista model setup */
8781static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8782 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8783 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8785 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8787 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8788 { } /* end */
8789};
8790
8791static struct hda_verb alc262_ultra_verbs[] = {
8792 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8793 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8795 /* Mic is on Node 0x19 */
8796 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8797 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8798 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8799 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8800 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8801 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8802 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8803 {}
8804};
8805
8806static struct hda_input_mux alc262_ultra_capture_source = {
8807 .num_items = 1,
8808 .items = {
8809 { "Mic", 0x1 },
8810 },
8811};
8812
8813/* mute/unmute internal speaker according to the hp jack and mute state */
8814static void alc262_ultra_automute(struct hda_codec *codec)
8815{
8816 struct alc_spec *spec = codec->spec;
8817 unsigned int mute;
8818 unsigned int present;
8819
8820 /* need to execute and sync at first */
8821 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8822 present = snd_hda_codec_read(codec, 0x15, 0,
8823 AC_VERB_GET_PIN_SENSE, 0);
8824 spec->jack_present = (present & 0x80000000) != 0;
8825 if (spec->jack_present) {
8826 /* mute internal speaker */
8827 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8828 HDA_AMP_MUTE, HDA_AMP_MUTE);
8829 } else {
8830 /* unmute internal speaker if necessary */
8831 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8832 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8833 HDA_AMP_MUTE, mute);
8834 }
8835}
8836
8837/* unsolicited event for HP jack sensing */
8838static void alc262_ultra_unsol_event(struct hda_codec *codec,
8839 unsigned int res)
8840{
8841 if ((res >> 26) != ALC880_HP_EVENT)
8842 return;
8843 alc262_ultra_automute(codec);
8844}
8845
df694daa 8846/* add playback controls from the parsed DAC table */
f12ab1e0
TI
8847static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8848 const struct auto_pin_cfg *cfg)
df694daa
KY
8849{
8850 hda_nid_t nid;
8851 int err;
8852
8853 spec->multiout.num_dacs = 1; /* only use one dac */
8854 spec->multiout.dac_nids = spec->private_dac_nids;
8855 spec->multiout.dac_nids[0] = 2;
8856
8857 nid = cfg->line_out_pins[0];
8858 if (nid) {
f12ab1e0
TI
8859 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8860 "Front Playback Volume",
8861 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8862 if (err < 0)
df694daa 8863 return err;
f12ab1e0
TI
8864 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8865 "Front Playback Switch",
8866 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8867 if (err < 0)
df694daa
KY
8868 return err;
8869 }
8870
82bc955f 8871 nid = cfg->speaker_pins[0];
df694daa
KY
8872 if (nid) {
8873 if (nid == 0x16) {
f12ab1e0
TI
8874 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8875 "Speaker Playback Volume",
8876 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8877 HDA_OUTPUT));
8878 if (err < 0)
df694daa 8879 return err;
f12ab1e0
TI
8880 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8881 "Speaker Playback Switch",
8882 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8883 HDA_OUTPUT));
8884 if (err < 0)
df694daa
KY
8885 return err;
8886 } else {
f12ab1e0
TI
8887 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8888 "Speaker Playback Switch",
8889 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8890 HDA_OUTPUT));
8891 if (err < 0)
df694daa
KY
8892 return err;
8893 }
8894 }
eb06ed8f 8895 nid = cfg->hp_pins[0];
df694daa
KY
8896 if (nid) {
8897 /* spec->multiout.hp_nid = 2; */
8898 if (nid == 0x16) {
f12ab1e0
TI
8899 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8900 "Headphone Playback Volume",
8901 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8902 HDA_OUTPUT));
8903 if (err < 0)
df694daa 8904 return err;
f12ab1e0
TI
8905 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8906 "Headphone Playback Switch",
8907 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8908 HDA_OUTPUT));
8909 if (err < 0)
df694daa
KY
8910 return err;
8911 } else {
f12ab1e0
TI
8912 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8913 "Headphone Playback Switch",
8914 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8915 HDA_OUTPUT));
8916 if (err < 0)
df694daa
KY
8917 return err;
8918 }
8919 }
f12ab1e0 8920 return 0;
df694daa
KY
8921}
8922
8923/* identical with ALC880 */
f12ab1e0
TI
8924#define alc262_auto_create_analog_input_ctls \
8925 alc880_auto_create_analog_input_ctls
df694daa
KY
8926
8927/*
8928 * generic initialization of ADC, input mixers and output mixers
8929 */
8930static struct hda_verb alc262_volume_init_verbs[] = {
8931 /*
8932 * Unmute ADC0-2 and set the default input to mic-in
8933 */
8934 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8935 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8936 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8937 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8938 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8939 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8940
cb53c626 8941 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 8942 * mixer widget
f12ab1e0
TI
8943 * Note: PASD motherboards uses the Line In 2 as the input for
8944 * front panel mic (mic 2)
df694daa
KY
8945 */
8946 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8951 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
8952
8953 /*
8954 * Set up output mixers (0x0c - 0x0f)
8955 */
8956 /* set vol=0 to output mixers */
8957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8958 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8959 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8960
8961 /* set up input amps for analog loopback */
8962 /* Amp Indices: DAC = 0, mixer = 1 */
8963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8964 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8969
8970 /* FIXME: use matrix-type input source selection */
8971 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8972 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8973 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8977 /* Input mixer2 */
8978 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8979 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8982 /* Input mixer3 */
8983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8987
8988 { }
8989};
8990
9c7f852e
TI
8991static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8992 /*
8993 * Unmute ADC0-2 and set the default input to mic-in
8994 */
8995 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8997 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9000 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9001
cb53c626 9002 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9003 * mixer widget
f12ab1e0
TI
9004 * Note: PASD motherboards uses the Line In 2 as the input for
9005 * front panel mic (mic 2)
9c7f852e
TI
9006 */
9007 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
9015
9016 /*
9017 * Set up output mixers (0x0c - 0x0e)
9018 */
9019 /* set vol=0 to output mixers */
9020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9021 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9023
9024 /* set up input amps for analog loopback */
9025 /* Amp Indices: DAC = 0, mixer = 1 */
9026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9028 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9032
ce875f07 9033 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
9034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9035 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9036
9037 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9039
9040 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9041 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9042
9043 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9044 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9046 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9047 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9048
9049 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9050 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9051 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9052 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9053 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9054 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9055
9056
9057 /* FIXME: use matrix-type input source selection */
9058 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9059 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9061 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9064 /* Input mixer2 */
9065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9066 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9069 /* Input mixer3 */
9070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9074
ce875f07
TI
9075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9076
9c7f852e
TI
9077 { }
9078};
9079
cd7509a4
KY
9080static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9081 /*
9082 * Unmute ADC0-2 and set the default input to mic-in
9083 */
9084 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9088 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9090
cb53c626 9091 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
9092 * mixer widget
9093 * Note: PASD motherboards uses the Line In 2 as the input for front
9094 * panel mic (mic 2)
9095 */
9096 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
9105 /*
9106 * Set up output mixers (0x0c - 0x0e)
9107 */
9108 /* set vol=0 to output mixers */
9109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9112
9113 /* set up input amps for analog loopback */
9114 /* Amp Indices: DAC = 0, mixer = 1 */
9115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9121
9122
9123 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9124 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9125 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9126 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9128 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9129 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9130
9131 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9132 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9133
9134 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9135 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9136
9137 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9138 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9139 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9140 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9141 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9142 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9143
9144 /* FIXME: use matrix-type input source selection */
9145 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9146 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9147 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9152 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9154 /* Input mixer2 */
9155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9160 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9162 /* Input mixer3 */
9163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9164 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9168 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9170
ce875f07
TI
9171 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9172
cd7509a4
KY
9173 { }
9174};
9175
cb53c626
TI
9176#ifdef CONFIG_SND_HDA_POWER_SAVE
9177#define alc262_loopbacks alc880_loopbacks
9178#endif
9179
df694daa
KY
9180/* pcm configuration: identiacal with ALC880 */
9181#define alc262_pcm_analog_playback alc880_pcm_analog_playback
9182#define alc262_pcm_analog_capture alc880_pcm_analog_capture
9183#define alc262_pcm_digital_playback alc880_pcm_digital_playback
9184#define alc262_pcm_digital_capture alc880_pcm_digital_capture
9185
9186/*
9187 * BIOS auto configuration
9188 */
9189static int alc262_parse_auto_config(struct hda_codec *codec)
9190{
9191 struct alc_spec *spec = codec->spec;
9192 int err;
9193 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9194
f12ab1e0
TI
9195 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9196 alc262_ignore);
9197 if (err < 0)
df694daa 9198 return err;
f12ab1e0 9199 if (!spec->autocfg.line_outs)
df694daa 9200 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
9201 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9202 if (err < 0)
9203 return err;
9204 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9205 if (err < 0)
df694daa
KY
9206 return err;
9207
9208 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9209
9210 if (spec->autocfg.dig_out_pin)
9211 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9212 if (spec->autocfg.dig_in_pin)
9213 spec->dig_in_nid = ALC262_DIGIN_NID;
9214
9215 if (spec->kctl_alloc)
9216 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9217
9218 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 9219 spec->num_mux_defs = 1;
df694daa
KY
9220 spec->input_mux = &spec->private_imux;
9221
776e184e
TI
9222 err = alc_auto_add_mic_boost(codec);
9223 if (err < 0)
9224 return err;
9225
df694daa
KY
9226 return 1;
9227}
9228
9229#define alc262_auto_init_multi_out alc882_auto_init_multi_out
9230#define alc262_auto_init_hp_out alc882_auto_init_hp_out
9231#define alc262_auto_init_analog_input alc882_auto_init_analog_input
9232
9233
9234/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 9235static void alc262_auto_init(struct hda_codec *codec)
df694daa 9236{
f6c7e546 9237 struct alc_spec *spec = codec->spec;
df694daa
KY
9238 alc262_auto_init_multi_out(codec);
9239 alc262_auto_init_hp_out(codec);
9240 alc262_auto_init_analog_input(codec);
f6c7e546
TI
9241 if (spec->unsol_event)
9242 alc_sku_automute(codec);
df694daa
KY
9243}
9244
9245/*
9246 * configuration and preset
9247 */
f5fcc13c
TI
9248static const char *alc262_models[ALC262_MODEL_LAST] = {
9249 [ALC262_BASIC] = "basic",
9250 [ALC262_HIPPO] = "hippo",
9251 [ALC262_HIPPO_1] = "hippo_1",
9252 [ALC262_FUJITSU] = "fujitsu",
9253 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 9254 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 9255 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 9256 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 9257 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
9258 [ALC262_BENQ_T31] = "benq-t31",
9259 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 9260 [ALC262_ULTRA] = "ultra",
f5fcc13c
TI
9261 [ALC262_AUTO] = "auto",
9262};
9263
9264static struct snd_pci_quirk alc262_cfg_tbl[] = {
9265 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9266 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 9267 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
9268 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9269 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 9270 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 9271 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 9272 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 9273 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 9274 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9275 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9276 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9277 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9278 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9279 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9280 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9281 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
9282 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9283 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9284 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
9285 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9286 ALC262_HP_TC_T5735),
8c427226 9287 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 9288 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 9289 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 9290 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 9291 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
9292 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9293 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 9294 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 9295 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
ac3e3741
TI
9296 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9297 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9298 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
9299 {}
9300};
9301
9302static struct alc_config_preset alc262_presets[] = {
9303 [ALC262_BASIC] = {
9304 .mixers = { alc262_base_mixer },
9305 .init_verbs = { alc262_init_verbs },
9306 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9307 .dac_nids = alc262_dac_nids,
9308 .hp_nid = 0x03,
9309 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9310 .channel_mode = alc262_modes,
a3bcba38 9311 .input_mux = &alc262_capture_source,
df694daa 9312 },
ccc656ce
KY
9313 [ALC262_HIPPO] = {
9314 .mixers = { alc262_base_mixer },
9315 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9316 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9317 .dac_nids = alc262_dac_nids,
9318 .hp_nid = 0x03,
9319 .dig_out_nid = ALC262_DIGOUT_NID,
9320 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9321 .channel_mode = alc262_modes,
9322 .input_mux = &alc262_capture_source,
9323 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9324 .init_hook = alc262_hippo_automute,
ccc656ce
KY
9325 },
9326 [ALC262_HIPPO_1] = {
9327 .mixers = { alc262_hippo1_mixer },
9328 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9329 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9330 .dac_nids = alc262_dac_nids,
9331 .hp_nid = 0x02,
9332 .dig_out_nid = ALC262_DIGOUT_NID,
9333 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9334 .channel_mode = alc262_modes,
9335 .input_mux = &alc262_capture_source,
9336 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 9337 .init_hook = alc262_hippo1_automute,
ccc656ce 9338 },
834be88d
TI
9339 [ALC262_FUJITSU] = {
9340 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
9341 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9342 alc262_fujitsu_unsol_verbs },
834be88d
TI
9343 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9344 .dac_nids = alc262_dac_nids,
9345 .hp_nid = 0x03,
9346 .dig_out_nid = ALC262_DIGOUT_NID,
9347 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9348 .channel_mode = alc262_modes,
9349 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 9350 .unsol_event = alc262_fujitsu_unsol_event,
834be88d 9351 },
9c7f852e
TI
9352 [ALC262_HP_BPC] = {
9353 .mixers = { alc262_HP_BPC_mixer },
9354 .init_verbs = { alc262_HP_BPC_init_verbs },
9355 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9356 .dac_nids = alc262_dac_nids,
9357 .hp_nid = 0x03,
9358 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9359 .channel_mode = alc262_modes,
9360 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
9361 .unsol_event = alc262_hp_bpc_unsol_event,
9362 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 9363 },
cd7509a4
KY
9364 [ALC262_HP_BPC_D7000_WF] = {
9365 .mixers = { alc262_HP_BPC_WildWest_mixer },
9366 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9367 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9368 .dac_nids = alc262_dac_nids,
9369 .hp_nid = 0x03,
9370 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9371 .channel_mode = alc262_modes,
accbe498 9372 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9373 .unsol_event = alc262_hp_wildwest_unsol_event,
9374 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9375 },
cd7509a4
KY
9376 [ALC262_HP_BPC_D7000_WL] = {
9377 .mixers = { alc262_HP_BPC_WildWest_mixer,
9378 alc262_HP_BPC_WildWest_option_mixer },
9379 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9380 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9381 .dac_nids = alc262_dac_nids,
9382 .hp_nid = 0x03,
9383 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9384 .channel_mode = alc262_modes,
accbe498 9385 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9386 .unsol_event = alc262_hp_wildwest_unsol_event,
9387 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9388 },
66d2a9d6
KY
9389 [ALC262_HP_TC_T5735] = {
9390 .mixers = { alc262_hp_t5735_mixer },
9391 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9392 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9393 .dac_nids = alc262_dac_nids,
9394 .hp_nid = 0x03,
9395 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9396 .channel_mode = alc262_modes,
9397 .input_mux = &alc262_capture_source,
9398 .unsol_event = alc262_hp_t5735_unsol_event,
9399 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
9400 },
9401 [ALC262_HP_RP5700] = {
9402 .mixers = { alc262_hp_rp5700_mixer },
9403 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9404 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9405 .dac_nids = alc262_dac_nids,
9406 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9407 .channel_mode = alc262_modes,
9408 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 9409 },
304dcaac
TI
9410 [ALC262_BENQ_ED8] = {
9411 .mixers = { alc262_base_mixer },
9412 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9413 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9414 .dac_nids = alc262_dac_nids,
9415 .hp_nid = 0x03,
9416 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9417 .channel_mode = alc262_modes,
9418 .input_mux = &alc262_capture_source,
f12ab1e0 9419 },
272a527c
KY
9420 [ALC262_SONY_ASSAMD] = {
9421 .mixers = { alc262_sony_mixer },
9422 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9423 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9424 .dac_nids = alc262_dac_nids,
9425 .hp_nid = 0x02,
9426 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9427 .channel_mode = alc262_modes,
9428 .input_mux = &alc262_capture_source,
9429 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9430 .init_hook = alc262_hippo_automute,
83c34218
KY
9431 },
9432 [ALC262_BENQ_T31] = {
9433 .mixers = { alc262_benq_t31_mixer },
9434 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9435 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9436 .dac_nids = alc262_dac_nids,
9437 .hp_nid = 0x03,
9438 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9439 .channel_mode = alc262_modes,
9440 .input_mux = &alc262_capture_source,
9441 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9442 .init_hook = alc262_hippo_automute,
272a527c 9443 },
f651b50b
TD
9444 [ALC262_ULTRA] = {
9445 .mixers = { alc262_ultra_mixer },
9446 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9447 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9448 .dac_nids = alc262_dac_nids,
9449 .hp_nid = 0x03,
9450 .dig_out_nid = ALC262_DIGOUT_NID,
9451 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9452 .channel_mode = alc262_modes,
9453 .input_mux = &alc262_ultra_capture_source,
9454 .unsol_event = alc262_ultra_unsol_event,
9455 .init_hook = alc262_ultra_automute,
9456 },
df694daa
KY
9457};
9458
9459static int patch_alc262(struct hda_codec *codec)
9460{
9461 struct alc_spec *spec;
9462 int board_config;
9463 int err;
9464
dc041e0b 9465 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
9466 if (spec == NULL)
9467 return -ENOMEM;
9468
9469 codec->spec = spec;
9470#if 0
f12ab1e0
TI
9471 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9472 * under-run
9473 */
df694daa
KY
9474 {
9475 int tmp;
9476 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9477 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9478 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9479 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9480 }
9481#endif
9482
f5fcc13c
TI
9483 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9484 alc262_models,
9485 alc262_cfg_tbl);
cd7509a4 9486
f5fcc13c 9487 if (board_config < 0) {
9c7f852e
TI
9488 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9489 "trying auto-probe from BIOS...\n");
df694daa
KY
9490 board_config = ALC262_AUTO;
9491 }
9492
9493 if (board_config == ALC262_AUTO) {
9494 /* automatic parse from the BIOS config */
9495 err = alc262_parse_auto_config(codec);
9496 if (err < 0) {
9497 alc_free(codec);
9498 return err;
f12ab1e0 9499 } else if (!err) {
9c7f852e
TI
9500 printk(KERN_INFO
9501 "hda_codec: Cannot set up configuration "
9502 "from BIOS. Using base mode...\n");
df694daa
KY
9503 board_config = ALC262_BASIC;
9504 }
9505 }
9506
9507 if (board_config != ALC262_AUTO)
9508 setup_preset(spec, &alc262_presets[board_config]);
9509
9510 spec->stream_name_analog = "ALC262 Analog";
9511 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9512 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9513
9514 spec->stream_name_digital = "ALC262 Digital";
9515 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9516 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9517
f12ab1e0 9518 if (!spec->adc_nids && spec->input_mux) {
df694daa 9519 /* check whether NID 0x07 is valid */
4a471b7d
TI
9520 unsigned int wcap = get_wcaps(codec, 0x07);
9521
f12ab1e0
TI
9522 /* get type */
9523 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9524 if (wcap != AC_WID_AUD_IN) {
9525 spec->adc_nids = alc262_adc_nids_alt;
9526 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 9527 spec->capsrc_nids = alc262_capsrc_nids_alt;
f12ab1e0
TI
9528 spec->mixers[spec->num_mixers] =
9529 alc262_capture_alt_mixer;
df694daa
KY
9530 spec->num_mixers++;
9531 } else {
9532 spec->adc_nids = alc262_adc_nids;
9533 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 9534 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
9535 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9536 spec->num_mixers++;
9537 }
9538 }
9539
2134ea4f
TI
9540 spec->vmaster_nid = 0x0c;
9541
df694daa
KY
9542 codec->patch_ops = alc_patch_ops;
9543 if (board_config == ALC262_AUTO)
ae6b813a 9544 spec->init_hook = alc262_auto_init;
cb53c626
TI
9545#ifdef CONFIG_SND_HDA_POWER_SAVE
9546 if (!spec->loopback.amplist)
9547 spec->loopback.amplist = alc262_loopbacks;
9548#endif
834be88d 9549
df694daa
KY
9550 return 0;
9551}
9552
a361d84b
KY
9553/*
9554 * ALC268 channel source setting (2 channel)
9555 */
9556#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9557#define alc268_modes alc260_modes
9558
9559static hda_nid_t alc268_dac_nids[2] = {
9560 /* front, hp */
9561 0x02, 0x03
9562};
9563
9564static hda_nid_t alc268_adc_nids[2] = {
9565 /* ADC0-1 */
9566 0x08, 0x07
9567};
9568
9569static hda_nid_t alc268_adc_nids_alt[1] = {
9570 /* ADC0 */
9571 0x08
9572};
9573
e1406348
TI
9574static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9575
a361d84b
KY
9576static struct snd_kcontrol_new alc268_base_mixer[] = {
9577 /* output mixer control */
9578 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9579 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9580 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9581 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9582 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9583 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9584 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9585 { }
9586};
9587
aef9d318
TI
9588/* bind Beep switches of both NID 0x0f and 0x10 */
9589static struct hda_bind_ctls alc268_bind_beep_sw = {
9590 .ops = &snd_hda_bind_sw,
9591 .values = {
9592 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
9593 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
9594 0
9595 },
9596};
9597
9598static struct snd_kcontrol_new alc268_beep_mixer[] = {
9599 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
9600 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
9601 { }
9602};
9603
d1a991a6
KY
9604static struct hda_verb alc268_eapd_verbs[] = {
9605 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9606 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9607 { }
9608};
9609
d273809e
TI
9610/* Toshiba specific */
9611#define alc268_toshiba_automute alc262_hippo_automute
9612
9613static struct hda_verb alc268_toshiba_verbs[] = {
9614 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9615 { } /* end */
9616};
9617
9618/* Acer specific */
889c4395 9619/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9620static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9621 .ops = &snd_hda_bind_vol,
9622 .values = {
9623 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9624 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9625 0
9626 },
9627};
9628
889c4395
TI
9629/* mute/unmute internal speaker according to the hp jack and mute state */
9630static void alc268_acer_automute(struct hda_codec *codec, int force)
9631{
9632 struct alc_spec *spec = codec->spec;
9633 unsigned int mute;
9634
9635 if (force || !spec->sense_updated) {
9636 unsigned int present;
9637 present = snd_hda_codec_read(codec, 0x14, 0,
9638 AC_VERB_GET_PIN_SENSE, 0);
9639 spec->jack_present = (present & 0x80000000) != 0;
9640 spec->sense_updated = 1;
9641 }
9642 if (spec->jack_present)
9643 mute = HDA_AMP_MUTE; /* mute internal speaker */
9644 else /* unmute internal speaker if necessary */
9645 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9646 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9647 HDA_AMP_MUTE, mute);
9648}
9649
9650
9651/* bind hp and internal speaker mute (with plug check) */
9652static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9653 struct snd_ctl_elem_value *ucontrol)
9654{
9655 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9656 long *valp = ucontrol->value.integer.value;
9657 int change;
9658
9659 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9660 HDA_AMP_MUTE,
9661 valp[0] ? 0 : HDA_AMP_MUTE);
9662 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9663 HDA_AMP_MUTE,
9664 valp[1] ? 0 : HDA_AMP_MUTE);
9665 if (change)
9666 alc268_acer_automute(codec, 0);
9667 return change;
9668}
d273809e
TI
9669
9670static struct snd_kcontrol_new alc268_acer_mixer[] = {
9671 /* output mixer control */
9672 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9673 {
9674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9675 .name = "Master Playback Switch",
9676 .info = snd_hda_mixer_amp_switch_info,
9677 .get = snd_hda_mixer_amp_switch_get,
9678 .put = alc268_acer_master_sw_put,
9679 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9680 },
33bf17ab
TI
9681 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9682 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9683 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9684 { }
9685};
9686
9687static struct hda_verb alc268_acer_verbs[] = {
9688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9690
9691 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9692 { }
9693};
9694
9695/* unsolicited event for HP jack sensing */
9696static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9697 unsigned int res)
9698{
889c4395 9699 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9700 return;
9701 alc268_toshiba_automute(codec);
9702}
9703
9704static void alc268_acer_unsol_event(struct hda_codec *codec,
9705 unsigned int res)
9706{
889c4395 9707 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9708 return;
9709 alc268_acer_automute(codec, 1);
9710}
9711
889c4395
TI
9712static void alc268_acer_init_hook(struct hda_codec *codec)
9713{
9714 alc268_acer_automute(codec, 1);
9715}
9716
3866f0b0
TI
9717static struct snd_kcontrol_new alc268_dell_mixer[] = {
9718 /* output mixer control */
9719 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9720 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9722 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9723 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9724 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9725 { }
9726};
9727
9728static struct hda_verb alc268_dell_verbs[] = {
9729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9730 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9731 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9732 { }
9733};
9734
9735/* mute/unmute internal speaker according to the hp jack and mute state */
9736static void alc268_dell_automute(struct hda_codec *codec)
9737{
9738 unsigned int present;
9739 unsigned int mute;
9740
9741 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9742 if (present & 0x80000000)
9743 mute = HDA_AMP_MUTE;
9744 else
9745 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9746 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9747 HDA_AMP_MUTE, mute);
9748}
9749
9750static void alc268_dell_unsol_event(struct hda_codec *codec,
9751 unsigned int res)
9752{
9753 if ((res >> 26) != ALC880_HP_EVENT)
9754 return;
9755 alc268_dell_automute(codec);
9756}
9757
9758#define alc268_dell_init_hook alc268_dell_automute
9759
a361d84b
KY
9760/*
9761 * generic initialization of ADC, input mixers and output mixers
9762 */
9763static struct hda_verb alc268_base_init_verbs[] = {
9764 /* Unmute DAC0-1 and set vol = 0 */
9765 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9766 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9767 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9768 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9769 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9770 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9771
9772 /*
9773 * Set up output mixers (0x0c - 0x0e)
9774 */
9775 /* set vol=0 to output mixers */
9776 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9779 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9780
9781 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9782 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9783
9784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9786 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9787 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9788 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9789 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9790 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9791 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9792
9793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9796 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9799 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
9800
9801 /* set PCBEEP vol = 0, mute connections */
9802 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9804 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 9805
a9b3aa8a
JZ
9806 /* Unmute Selector 23h,24h and set the default input to mic-in */
9807
9808 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9810 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 9812
a361d84b
KY
9813 { }
9814};
9815
9816/*
9817 * generic initialization of ADC, input mixers and output mixers
9818 */
9819static struct hda_verb alc268_volume_init_verbs[] = {
9820 /* set output DAC */
9821 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9822 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9823 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9824 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9825
9826 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9827 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9828 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9829 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9830 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9831
9832 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9833 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9834 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9836 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9837
9838 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9839 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9841 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9842
aef9d318
TI
9843 /* set PCBEEP vol = 0, mute connections */
9844 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9846 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
9847
9848 { }
9849};
9850
9851#define alc268_mux_enum_info alc_mux_enum_info
9852#define alc268_mux_enum_get alc_mux_enum_get
e1406348 9853#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
9854
9855static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9856 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9857 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9858 {
9859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9860 /* The multiple "Capture Source" controls confuse alsamixer
9861 * So call somewhat different..
a361d84b
KY
9862 */
9863 /* .name = "Capture Source", */
9864 .name = "Input Source",
9865 .count = 1,
9866 .info = alc268_mux_enum_info,
9867 .get = alc268_mux_enum_get,
9868 .put = alc268_mux_enum_put,
9869 },
9870 { } /* end */
9871};
9872
9873static struct snd_kcontrol_new alc268_capture_mixer[] = {
9874 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9875 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9876 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9877 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9878 {
9879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9880 /* The multiple "Capture Source" controls confuse alsamixer
9881 * So call somewhat different..
a361d84b
KY
9882 */
9883 /* .name = "Capture Source", */
9884 .name = "Input Source",
9885 .count = 2,
9886 .info = alc268_mux_enum_info,
9887 .get = alc268_mux_enum_get,
9888 .put = alc268_mux_enum_put,
9889 },
9890 { } /* end */
9891};
9892
9893static struct hda_input_mux alc268_capture_source = {
9894 .num_items = 4,
9895 .items = {
9896 { "Mic", 0x0 },
9897 { "Front Mic", 0x1 },
9898 { "Line", 0x2 },
9899 { "CD", 0x3 },
9900 },
9901};
9902
86c53bd2
JW
9903#ifdef CONFIG_SND_DEBUG
9904static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
9905 /* Volume widgets */
9906 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9907 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9908 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9909 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9910 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9911 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9912 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9913 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9914 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9915 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9916 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9917 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9918 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
9919 /* The below appears problematic on some hardwares */
9920 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
9921 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9922 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9923 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9924 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9925
9926 /* Modes for retasking pin widgets */
9927 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9928 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9929 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9930 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9931
9932 /* Controls for GPIO pins, assuming they are configured as outputs */
9933 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9934 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9935 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9936 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9937
9938 /* Switches to allow the digital SPDIF output pin to be enabled.
9939 * The ALC268 does not have an SPDIF input.
9940 */
9941 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9942
9943 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9944 * this output to turn on an external amplifier.
9945 */
9946 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9947 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9948
9949 { } /* end */
9950};
9951#endif
9952
a361d84b
KY
9953/* create input playback/capture controls for the given pin */
9954static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9955 const char *ctlname, int idx)
9956{
9957 char name[32];
9958 int err;
9959
9960 sprintf(name, "%s Playback Volume", ctlname);
9961 if (nid == 0x14) {
9962 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9963 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9964 HDA_OUTPUT));
9965 if (err < 0)
9966 return err;
9967 } else if (nid == 0x15) {
9968 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9969 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9970 HDA_OUTPUT));
9971 if (err < 0)
9972 return err;
9973 } else
9974 return -1;
9975 sprintf(name, "%s Playback Switch", ctlname);
9976 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9977 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9978 if (err < 0)
9979 return err;
9980 return 0;
9981}
9982
9983/* add playback controls from the parsed DAC table */
9984static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9985 const struct auto_pin_cfg *cfg)
9986{
9987 hda_nid_t nid;
9988 int err;
9989
9990 spec->multiout.num_dacs = 2; /* only use one dac */
9991 spec->multiout.dac_nids = spec->private_dac_nids;
9992 spec->multiout.dac_nids[0] = 2;
9993 spec->multiout.dac_nids[1] = 3;
9994
9995 nid = cfg->line_out_pins[0];
9996 if (nid)
9997 alc268_new_analog_output(spec, nid, "Front", 0);
9998
9999 nid = cfg->speaker_pins[0];
10000 if (nid == 0x1d) {
10001 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10002 "Speaker Playback Volume",
10003 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10004 if (err < 0)
10005 return err;
10006 }
10007 nid = cfg->hp_pins[0];
10008 if (nid)
10009 alc268_new_analog_output(spec, nid, "Headphone", 0);
10010
10011 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10012 if (nid == 0x16) {
10013 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10014 "Mono Playback Switch",
10015 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10016 if (err < 0)
10017 return err;
10018 }
10019 return 0;
10020}
10021
10022/* create playback/capture controls for input pins */
10023static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10024 const struct auto_pin_cfg *cfg)
10025{
10026 struct hda_input_mux *imux = &spec->private_imux;
10027 int i, idx1;
10028
10029 for (i = 0; i < AUTO_PIN_LAST; i++) {
10030 switch(cfg->input_pins[i]) {
10031 case 0x18:
10032 idx1 = 0; /* Mic 1 */
10033 break;
10034 case 0x19:
10035 idx1 = 1; /* Mic 2 */
10036 break;
10037 case 0x1a:
10038 idx1 = 2; /* Line In */
10039 break;
10040 case 0x1c:
10041 idx1 = 3; /* CD */
10042 break;
10043 default:
10044 continue;
10045 }
10046 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10047 imux->items[imux->num_items].index = idx1;
10048 imux->num_items++;
10049 }
10050 return 0;
10051}
10052
10053static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10054{
10055 struct alc_spec *spec = codec->spec;
10056 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10057 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10058 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10059 unsigned int dac_vol1, dac_vol2;
10060
10061 if (speaker_nid) {
10062 snd_hda_codec_write(codec, speaker_nid, 0,
10063 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10064 snd_hda_codec_write(codec, 0x0f, 0,
10065 AC_VERB_SET_AMP_GAIN_MUTE,
10066 AMP_IN_UNMUTE(1));
10067 snd_hda_codec_write(codec, 0x10, 0,
10068 AC_VERB_SET_AMP_GAIN_MUTE,
10069 AMP_IN_UNMUTE(1));
10070 } else {
10071 snd_hda_codec_write(codec, 0x0f, 0,
10072 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10073 snd_hda_codec_write(codec, 0x10, 0,
10074 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10075 }
10076
10077 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10078 if (line_nid == 0x14)
10079 dac_vol2 = AMP_OUT_ZERO;
10080 else if (line_nid == 0x15)
10081 dac_vol1 = AMP_OUT_ZERO;
10082 if (hp_nid == 0x14)
10083 dac_vol2 = AMP_OUT_ZERO;
10084 else if (hp_nid == 0x15)
10085 dac_vol1 = AMP_OUT_ZERO;
10086 if (line_nid != 0x16 || hp_nid != 0x16 ||
10087 spec->autocfg.line_out_pins[1] != 0x16 ||
10088 spec->autocfg.line_out_pins[2] != 0x16)
10089 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10090
10091 snd_hda_codec_write(codec, 0x02, 0,
10092 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10093 snd_hda_codec_write(codec, 0x03, 0,
10094 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10095}
10096
10097/* pcm configuration: identiacal with ALC880 */
10098#define alc268_pcm_analog_playback alc880_pcm_analog_playback
10099#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 10100#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
10101#define alc268_pcm_digital_playback alc880_pcm_digital_playback
10102
10103/*
10104 * BIOS auto configuration
10105 */
10106static int alc268_parse_auto_config(struct hda_codec *codec)
10107{
10108 struct alc_spec *spec = codec->spec;
10109 int err;
10110 static hda_nid_t alc268_ignore[] = { 0 };
10111
10112 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10113 alc268_ignore);
10114 if (err < 0)
10115 return err;
10116 if (!spec->autocfg.line_outs)
10117 return 0; /* can't find valid BIOS pin config */
10118
10119 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10120 if (err < 0)
10121 return err;
10122 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10123 if (err < 0)
10124 return err;
10125
10126 spec->multiout.max_channels = 2;
10127
10128 /* digital only support output */
10129 if (spec->autocfg.dig_out_pin)
10130 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10131
10132 if (spec->kctl_alloc)
10133 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10134
aef9d318
TI
10135 if (spec->autocfg.speaker_pins[0] != 0x1d)
10136 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10137
a361d84b
KY
10138 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10139 spec->num_mux_defs = 1;
10140 spec->input_mux = &spec->private_imux;
10141
776e184e
TI
10142 err = alc_auto_add_mic_boost(codec);
10143 if (err < 0)
10144 return err;
10145
a361d84b
KY
10146 return 1;
10147}
10148
10149#define alc268_auto_init_multi_out alc882_auto_init_multi_out
10150#define alc268_auto_init_hp_out alc882_auto_init_hp_out
10151#define alc268_auto_init_analog_input alc882_auto_init_analog_input
10152
10153/* init callback for auto-configuration model -- overriding the default init */
10154static void alc268_auto_init(struct hda_codec *codec)
10155{
f6c7e546 10156 struct alc_spec *spec = codec->spec;
a361d84b
KY
10157 alc268_auto_init_multi_out(codec);
10158 alc268_auto_init_hp_out(codec);
10159 alc268_auto_init_mono_speaker_out(codec);
10160 alc268_auto_init_analog_input(codec);
f6c7e546
TI
10161 if (spec->unsol_event)
10162 alc_sku_automute(codec);
a361d84b
KY
10163}
10164
10165/*
10166 * configuration and preset
10167 */
10168static const char *alc268_models[ALC268_MODEL_LAST] = {
10169 [ALC268_3ST] = "3stack",
983f8ae4 10170 [ALC268_TOSHIBA] = "toshiba",
d273809e 10171 [ALC268_ACER] = "acer",
3866f0b0 10172 [ALC268_DELL] = "dell",
f12462c5 10173 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
10174#ifdef CONFIG_SND_DEBUG
10175 [ALC268_TEST] = "test",
10176#endif
a361d84b
KY
10177 [ALC268_AUTO] = "auto",
10178};
10179
10180static struct snd_pci_quirk alc268_cfg_tbl[] = {
ac3e3741 10181 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 10182 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 10183 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 10184 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
3866f0b0 10185 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 10186 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 10187 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 10188 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 10189 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
b875bf3a 10190 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
f12462c5 10191 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
10192 {}
10193};
10194
10195static struct alc_config_preset alc268_presets[] = {
10196 [ALC268_3ST] = {
aef9d318
TI
10197 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10198 alc268_beep_mixer },
a361d84b
KY
10199 .init_verbs = { alc268_base_init_verbs },
10200 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10201 .dac_nids = alc268_dac_nids,
10202 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10203 .adc_nids = alc268_adc_nids_alt,
e1406348 10204 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
10205 .hp_nid = 0x03,
10206 .dig_out_nid = ALC268_DIGOUT_NID,
10207 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10208 .channel_mode = alc268_modes,
10209 .input_mux = &alc268_capture_source,
10210 },
d1a991a6 10211 [ALC268_TOSHIBA] = {
aef9d318
TI
10212 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10213 alc268_beep_mixer },
d273809e
TI
10214 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10215 alc268_toshiba_verbs },
d1a991a6
KY
10216 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10217 .dac_nids = alc268_dac_nids,
10218 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10219 .adc_nids = alc268_adc_nids_alt,
e1406348 10220 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
10221 .hp_nid = 0x03,
10222 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10223 .channel_mode = alc268_modes,
10224 .input_mux = &alc268_capture_source,
d273809e
TI
10225 .unsol_event = alc268_toshiba_unsol_event,
10226 .init_hook = alc268_toshiba_automute,
10227 },
10228 [ALC268_ACER] = {
aef9d318
TI
10229 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10230 alc268_beep_mixer },
d273809e
TI
10231 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10232 alc268_acer_verbs },
10233 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10234 .dac_nids = alc268_dac_nids,
10235 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10236 .adc_nids = alc268_adc_nids_alt,
e1406348 10237 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
10238 .hp_nid = 0x02,
10239 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10240 .channel_mode = alc268_modes,
10241 .input_mux = &alc268_capture_source,
10242 .unsol_event = alc268_acer_unsol_event,
889c4395 10243 .init_hook = alc268_acer_init_hook,
d1a991a6 10244 },
3866f0b0 10245 [ALC268_DELL] = {
aef9d318 10246 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
10247 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10248 alc268_dell_verbs },
10249 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10250 .dac_nids = alc268_dac_nids,
10251 .hp_nid = 0x02,
10252 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10253 .channel_mode = alc268_modes,
10254 .unsol_event = alc268_dell_unsol_event,
10255 .init_hook = alc268_dell_init_hook,
10256 .input_mux = &alc268_capture_source,
10257 },
f12462c5 10258 [ALC268_ZEPTO] = {
aef9d318
TI
10259 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10260 alc268_beep_mixer },
f12462c5
MT
10261 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10262 alc268_toshiba_verbs },
10263 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10264 .dac_nids = alc268_dac_nids,
10265 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10266 .adc_nids = alc268_adc_nids_alt,
e1406348 10267 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
10268 .hp_nid = 0x03,
10269 .dig_out_nid = ALC268_DIGOUT_NID,
10270 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10271 .channel_mode = alc268_modes,
10272 .input_mux = &alc268_capture_source,
10273 .unsol_event = alc268_toshiba_unsol_event,
10274 .init_hook = alc268_toshiba_automute
10275 },
86c53bd2
JW
10276#ifdef CONFIG_SND_DEBUG
10277 [ALC268_TEST] = {
10278 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10279 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10280 alc268_volume_init_verbs },
10281 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10282 .dac_nids = alc268_dac_nids,
10283 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10284 .adc_nids = alc268_adc_nids_alt,
e1406348 10285 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
10286 .hp_nid = 0x03,
10287 .dig_out_nid = ALC268_DIGOUT_NID,
10288 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10289 .channel_mode = alc268_modes,
10290 .input_mux = &alc268_capture_source,
10291 },
10292#endif
a361d84b
KY
10293};
10294
10295static int patch_alc268(struct hda_codec *codec)
10296{
10297 struct alc_spec *spec;
10298 int board_config;
10299 int err;
10300
10301 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10302 if (spec == NULL)
10303 return -ENOMEM;
10304
10305 codec->spec = spec;
10306
10307 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10308 alc268_models,
10309 alc268_cfg_tbl);
10310
10311 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10312 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10313 "trying auto-probe from BIOS...\n");
10314 board_config = ALC268_AUTO;
10315 }
10316
10317 if (board_config == ALC268_AUTO) {
10318 /* automatic parse from the BIOS config */
10319 err = alc268_parse_auto_config(codec);
10320 if (err < 0) {
10321 alc_free(codec);
10322 return err;
10323 } else if (!err) {
10324 printk(KERN_INFO
10325 "hda_codec: Cannot set up configuration "
10326 "from BIOS. Using base mode...\n");
10327 board_config = ALC268_3ST;
10328 }
10329 }
10330
10331 if (board_config != ALC268_AUTO)
10332 setup_preset(spec, &alc268_presets[board_config]);
10333
10334 spec->stream_name_analog = "ALC268 Analog";
10335 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10336 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 10337 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b
KY
10338
10339 spec->stream_name_digital = "ALC268 Digital";
10340 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10341
aef9d318
TI
10342 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10343 /* override the amp caps for beep generator */
10344 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10345 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10346 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10347 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10348 (0 << AC_AMPCAP_MUTE_SHIFT));
10349
3866f0b0
TI
10350 if (!spec->adc_nids && spec->input_mux) {
10351 /* check whether NID 0x07 is valid */
10352 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 10353 int i;
3866f0b0
TI
10354
10355 /* get type */
10356 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 10357 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
10358 spec->adc_nids = alc268_adc_nids_alt;
10359 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10360 spec->mixers[spec->num_mixers] =
a361d84b 10361 alc268_capture_alt_mixer;
3866f0b0
TI
10362 spec->num_mixers++;
10363 } else {
10364 spec->adc_nids = alc268_adc_nids;
10365 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10366 spec->mixers[spec->num_mixers] =
10367 alc268_capture_mixer;
10368 spec->num_mixers++;
a361d84b 10369 }
e1406348 10370 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
10371 /* set default input source */
10372 for (i = 0; i < spec->num_adc_nids; i++)
10373 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
10374 0, AC_VERB_SET_CONNECT_SEL,
10375 spec->input_mux->items[0].index);
a361d84b 10376 }
2134ea4f
TI
10377
10378 spec->vmaster_nid = 0x02;
10379
a361d84b
KY
10380 codec->patch_ops = alc_patch_ops;
10381 if (board_config == ALC268_AUTO)
10382 spec->init_hook = alc268_auto_init;
10383
10384 return 0;
10385}
10386
f6a92248
KY
10387/*
10388 * ALC269 channel source setting (2 channel)
10389 */
10390#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10391
10392#define alc269_dac_nids alc260_dac_nids
10393
10394static hda_nid_t alc269_adc_nids[1] = {
10395 /* ADC1 */
10396 0x07,
10397};
10398
10399#define alc269_modes alc260_modes
10400#define alc269_capture_source alc880_lg_lw_capture_source
10401
10402static struct snd_kcontrol_new alc269_base_mixer[] = {
10403 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10404 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10405 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10406 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10407 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10408 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10409 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10410 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10412 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10414 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10415 { } /* end */
10416};
10417
10418/* capture mixer elements */
10419static struct snd_kcontrol_new alc269_capture_mixer[] = {
10420 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10421 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10422 {
10423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10424 /* The multiple "Capture Source" controls confuse alsamixer
10425 * So call somewhat different..
f6a92248
KY
10426 */
10427 /* .name = "Capture Source", */
10428 .name = "Input Source",
10429 .count = 1,
10430 .info = alc_mux_enum_info,
10431 .get = alc_mux_enum_get,
10432 .put = alc_mux_enum_put,
10433 },
10434 { } /* end */
10435};
10436
10437/*
10438 * generic initialization of ADC, input mixers and output mixers
10439 */
10440static struct hda_verb alc269_init_verbs[] = {
10441 /*
10442 * Unmute ADC0 and set the default input to mic-in
10443 */
10444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10445
10446 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10447 * analog-loopback mixer widget
10448 * Note: PASD motherboards uses the Line In 2 as the input for
10449 * front panel mic (mic 2)
10450 */
10451 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10457
10458 /*
10459 * Set up output mixers (0x0c - 0x0e)
10460 */
10461 /* set vol=0 to output mixers */
10462 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10463 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10464
10465 /* set up input amps for analog loopback */
10466 /* Amp Indices: DAC = 0, mixer = 1 */
10467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10468 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10469 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10470 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10471 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10472 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10473
10474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10477 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10478 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10479 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10480 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10481
10482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10484 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10485 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10486 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10487 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10488 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10489
10490 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10492
10493 /* FIXME: use matrix-type input source selection */
10494 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10495 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10497 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10498 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10499 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10500
10501 /* set EAPD */
10502 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10503 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10504 { }
10505};
10506
10507/* add playback controls from the parsed DAC table */
10508static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10509 const struct auto_pin_cfg *cfg)
10510{
10511 hda_nid_t nid;
10512 int err;
10513
10514 spec->multiout.num_dacs = 1; /* only use one dac */
10515 spec->multiout.dac_nids = spec->private_dac_nids;
10516 spec->multiout.dac_nids[0] = 2;
10517
10518 nid = cfg->line_out_pins[0];
10519 if (nid) {
10520 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10521 "Front Playback Volume",
10522 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10523 if (err < 0)
10524 return err;
10525 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10526 "Front Playback Switch",
10527 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10528 if (err < 0)
10529 return err;
10530 }
10531
10532 nid = cfg->speaker_pins[0];
10533 if (nid) {
10534 if (!cfg->line_out_pins[0]) {
10535 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10536 "Speaker Playback Volume",
10537 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10538 HDA_OUTPUT));
10539 if (err < 0)
10540 return err;
10541 }
10542 if (nid == 0x16) {
10543 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10544 "Speaker Playback Switch",
10545 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10546 HDA_OUTPUT));
10547 if (err < 0)
10548 return err;
10549 } else {
10550 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10551 "Speaker Playback Switch",
10552 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10553 HDA_OUTPUT));
10554 if (err < 0)
10555 return err;
10556 }
10557 }
10558 nid = cfg->hp_pins[0];
10559 if (nid) {
10560 /* spec->multiout.hp_nid = 2; */
10561 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10562 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10563 "Headphone Playback Volume",
10564 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10565 HDA_OUTPUT));
10566 if (err < 0)
10567 return err;
10568 }
10569 if (nid == 0x16) {
10570 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10571 "Headphone Playback Switch",
10572 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10573 HDA_OUTPUT));
10574 if (err < 0)
10575 return err;
10576 } else {
10577 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10578 "Headphone Playback Switch",
10579 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10580 HDA_OUTPUT));
10581 if (err < 0)
10582 return err;
10583 }
10584 }
10585 return 0;
10586}
10587
10588#define alc269_auto_create_analog_input_ctls \
10589 alc880_auto_create_analog_input_ctls
10590
10591#ifdef CONFIG_SND_HDA_POWER_SAVE
10592#define alc269_loopbacks alc880_loopbacks
10593#endif
10594
10595/* pcm configuration: identiacal with ALC880 */
10596#define alc269_pcm_analog_playback alc880_pcm_analog_playback
10597#define alc269_pcm_analog_capture alc880_pcm_analog_capture
10598#define alc269_pcm_digital_playback alc880_pcm_digital_playback
10599#define alc269_pcm_digital_capture alc880_pcm_digital_capture
10600
10601/*
10602 * BIOS auto configuration
10603 */
10604static int alc269_parse_auto_config(struct hda_codec *codec)
10605{
10606 struct alc_spec *spec = codec->spec;
10607 int err;
10608 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10609
10610 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10611 alc269_ignore);
10612 if (err < 0)
10613 return err;
10614
10615 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10616 if (err < 0)
10617 return err;
10618 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10619 if (err < 0)
10620 return err;
10621
10622 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10623
10624 if (spec->autocfg.dig_out_pin)
10625 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10626
10627 if (spec->kctl_alloc)
10628 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10629
10630 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10631 spec->num_mux_defs = 1;
10632 spec->input_mux = &spec->private_imux;
10633
10634 err = alc_auto_add_mic_boost(codec);
10635 if (err < 0)
10636 return err;
10637
10638 return 1;
10639}
10640
10641#define alc269_auto_init_multi_out alc882_auto_init_multi_out
10642#define alc269_auto_init_hp_out alc882_auto_init_hp_out
10643#define alc269_auto_init_analog_input alc882_auto_init_analog_input
10644
10645
10646/* init callback for auto-configuration model -- overriding the default init */
10647static void alc269_auto_init(struct hda_codec *codec)
10648{
f6c7e546 10649 struct alc_spec *spec = codec->spec;
f6a92248
KY
10650 alc269_auto_init_multi_out(codec);
10651 alc269_auto_init_hp_out(codec);
10652 alc269_auto_init_analog_input(codec);
f6c7e546
TI
10653 if (spec->unsol_event)
10654 alc_sku_automute(codec);
f6a92248
KY
10655}
10656
10657/*
10658 * configuration and preset
10659 */
10660static const char *alc269_models[ALC269_MODEL_LAST] = {
10661 [ALC269_BASIC] = "basic",
10662};
10663
10664static struct snd_pci_quirk alc269_cfg_tbl[] = {
10665 {}
10666};
10667
10668static struct alc_config_preset alc269_presets[] = {
10669 [ALC269_BASIC] = {
10670 .mixers = { alc269_base_mixer },
10671 .init_verbs = { alc269_init_verbs },
10672 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10673 .dac_nids = alc269_dac_nids,
10674 .hp_nid = 0x03,
10675 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10676 .channel_mode = alc269_modes,
10677 .input_mux = &alc269_capture_source,
10678 },
10679};
10680
10681static int patch_alc269(struct hda_codec *codec)
10682{
10683 struct alc_spec *spec;
10684 int board_config;
10685 int err;
10686
10687 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10688 if (spec == NULL)
10689 return -ENOMEM;
10690
10691 codec->spec = spec;
10692
10693 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10694 alc269_models,
10695 alc269_cfg_tbl);
10696
10697 if (board_config < 0) {
10698 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10699 "trying auto-probe from BIOS...\n");
10700 board_config = ALC269_AUTO;
10701 }
10702
10703 if (board_config == ALC269_AUTO) {
10704 /* automatic parse from the BIOS config */
10705 err = alc269_parse_auto_config(codec);
10706 if (err < 0) {
10707 alc_free(codec);
10708 return err;
10709 } else if (!err) {
10710 printk(KERN_INFO
10711 "hda_codec: Cannot set up configuration "
10712 "from BIOS. Using base mode...\n");
10713 board_config = ALC269_BASIC;
10714 }
10715 }
10716
10717 if (board_config != ALC269_AUTO)
10718 setup_preset(spec, &alc269_presets[board_config]);
10719
10720 spec->stream_name_analog = "ALC269 Analog";
10721 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10722 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10723
10724 spec->stream_name_digital = "ALC269 Digital";
10725 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10726 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10727
10728 spec->adc_nids = alc269_adc_nids;
10729 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10730 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10731 spec->num_mixers++;
10732
10733 codec->patch_ops = alc_patch_ops;
10734 if (board_config == ALC269_AUTO)
10735 spec->init_hook = alc269_auto_init;
10736#ifdef CONFIG_SND_HDA_POWER_SAVE
10737 if (!spec->loopback.amplist)
10738 spec->loopback.amplist = alc269_loopbacks;
10739#endif
10740
10741 return 0;
10742}
10743
df694daa
KY
10744/*
10745 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10746 */
10747
10748/*
10749 * set the path ways for 2 channel output
10750 * need to set the codec line out and mic 1 pin widgets to inputs
10751 */
10752static struct hda_verb alc861_threestack_ch2_init[] = {
10753 /* set pin widget 1Ah (line in) for input */
10754 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10755 /* set pin widget 18h (mic1/2) for input, for mic also enable
10756 * the vref
10757 */
df694daa
KY
10758 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10759
9c7f852e
TI
10760 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10761#if 0
10762 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10763 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10764#endif
df694daa
KY
10765 { } /* end */
10766};
10767/*
10768 * 6ch mode
10769 * need to set the codec line out and mic 1 pin widgets to outputs
10770 */
10771static struct hda_verb alc861_threestack_ch6_init[] = {
10772 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10773 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10774 /* set pin widget 18h (mic1) for output (CLFE)*/
10775 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10776
10777 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 10778 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 10779
9c7f852e
TI
10780 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10781#if 0
10782 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10783 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10784#endif
df694daa
KY
10785 { } /* end */
10786};
10787
10788static struct hda_channel_mode alc861_threestack_modes[2] = {
10789 { 2, alc861_threestack_ch2_init },
10790 { 6, alc861_threestack_ch6_init },
10791};
22309c3e
TI
10792/* Set mic1 as input and unmute the mixer */
10793static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10794 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10795 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10796 { } /* end */
10797};
10798/* Set mic1 as output and mute mixer */
10799static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10800 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10801 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10802 { } /* end */
10803};
10804
10805static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10806 { 2, alc861_uniwill_m31_ch2_init },
10807 { 4, alc861_uniwill_m31_ch4_init },
10808};
df694daa 10809
7cdbff94
MD
10810/* Set mic1 and line-in as input and unmute the mixer */
10811static struct hda_verb alc861_asus_ch2_init[] = {
10812 /* set pin widget 1Ah (line in) for input */
10813 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10814 /* set pin widget 18h (mic1/2) for input, for mic also enable
10815 * the vref
10816 */
7cdbff94
MD
10817 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10818
10819 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10820#if 0
10821 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10822 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10823#endif
10824 { } /* end */
10825};
10826/* Set mic1 nad line-in as output and mute mixer */
10827static struct hda_verb alc861_asus_ch6_init[] = {
10828 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10829 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10830 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10831 /* set pin widget 18h (mic1) for output (CLFE)*/
10832 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10833 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10834 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10835 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10836
10837 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10838#if 0
10839 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10840 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10841#endif
10842 { } /* end */
10843};
10844
10845static struct hda_channel_mode alc861_asus_modes[2] = {
10846 { 2, alc861_asus_ch2_init },
10847 { 6, alc861_asus_ch6_init },
10848};
10849
df694daa
KY
10850/* patch-ALC861 */
10851
10852static struct snd_kcontrol_new alc861_base_mixer[] = {
10853 /* output mixer control */
10854 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10855 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10856 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10857 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10858 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10859
10860 /*Input mixer control */
10861 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10862 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10863 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10864 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10865 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10866 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10867 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10868 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10869 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10870 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10871
df694daa
KY
10872 /* Capture mixer control */
10873 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10874 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10875 {
10876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10877 .name = "Capture Source",
10878 .count = 1,
10879 .info = alc_mux_enum_info,
10880 .get = alc_mux_enum_get,
10881 .put = alc_mux_enum_put,
10882 },
10883 { } /* end */
10884};
10885
10886static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10887 /* output mixer control */
10888 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10889 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10890 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10891 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10892 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10893
10894 /* Input mixer control */
10895 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10896 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10897 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10898 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10899 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10900 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10902 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10903 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10904 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10905
df694daa
KY
10906 /* Capture mixer control */
10907 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10908 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10909 {
10910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10911 .name = "Capture Source",
10912 .count = 1,
10913 .info = alc_mux_enum_info,
10914 .get = alc_mux_enum_get,
10915 .put = alc_mux_enum_put,
10916 },
10917 {
10918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10919 .name = "Channel Mode",
10920 .info = alc_ch_mode_info,
10921 .get = alc_ch_mode_get,
10922 .put = alc_ch_mode_put,
10923 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10924 },
10925 { } /* end */
a53d1aec
TD
10926};
10927
d1d985f0 10928static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
10929 /* output mixer control */
10930 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10931 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10932 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10933
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 { } /* end */
f12ab1e0 10947};
a53d1aec 10948
22309c3e
TI
10949static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10950 /* output mixer control */
10951 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10952 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10953 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10954 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10955 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10956
10957 /* Input mixer control */
10958 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10959 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10960 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10961 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10962 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10963 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10965 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10966 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10967 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10968
22309c3e
TI
10969 /* Capture mixer control */
10970 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10971 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10972 {
10973 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10974 .name = "Capture Source",
10975 .count = 1,
10976 .info = alc_mux_enum_info,
10977 .get = alc_mux_enum_get,
10978 .put = alc_mux_enum_put,
10979 },
10980 {
10981 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10982 .name = "Channel Mode",
10983 .info = alc_ch_mode_info,
10984 .get = alc_ch_mode_get,
10985 .put = alc_ch_mode_put,
10986 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10987 },
10988 { } /* end */
f12ab1e0 10989};
7cdbff94
MD
10990
10991static struct snd_kcontrol_new alc861_asus_mixer[] = {
10992 /* output mixer control */
10993 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10994 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10995 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10996 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10997 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10998
10999 /* Input mixer control */
11000 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11001 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11002 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11003 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11004 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11005 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11007 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11008 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
11009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
11010
7cdbff94
MD
11011 /* Capture mixer control */
11012 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11013 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11014 {
11015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11016 .name = "Capture Source",
11017 .count = 1,
11018 .info = alc_mux_enum_info,
11019 .get = alc_mux_enum_get,
11020 .put = alc_mux_enum_put,
11021 },
11022 {
11023 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11024 .name = "Channel Mode",
11025 .info = alc_ch_mode_info,
11026 .get = alc_ch_mode_get,
11027 .put = alc_ch_mode_put,
11028 .private_value = ARRAY_SIZE(alc861_asus_modes),
11029 },
11030 { }
56bb0cab
TI
11031};
11032
11033/* additional mixer */
d1d985f0 11034static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
11035 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11036 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11037 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
11038 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
11039 { }
11040};
7cdbff94 11041
df694daa
KY
11042/*
11043 * generic initialization of ADC, input mixers and output mixers
11044 */
11045static struct hda_verb alc861_base_init_verbs[] = {
11046 /*
11047 * Unmute ADC0 and set the default input to mic-in
11048 */
11049 /* port-A for surround (rear panel) */
11050 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11051 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
11052 /* port-B for mic-in (rear panel) with vref */
11053 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11054 /* port-C for line-in (rear panel) */
11055 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11056 /* port-D for Front */
11057 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11058 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11059 /* port-E for HP out (front panel) */
11060 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11061 /* route front PCM to HP */
9dece1d7 11062 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
11063 /* port-F for mic-in (front panel) with vref */
11064 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11065 /* port-G for CLFE (rear panel) */
11066 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11067 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11068 /* port-H for side (rear panel) */
11069 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11070 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
11071 /* CD-in */
11072 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11073 /* route front mic to ADC1*/
11074 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11076
11077 /* Unmute DAC0~3 & spdif out*/
11078 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11079 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11080 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11081 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11083
11084 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11085 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11086 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11087 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11088 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11089
11090 /* Unmute Stereo Mixer 15 */
11091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11094 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11095
11096 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11097 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11098 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11099 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11100 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11101 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11103 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11104 /* hp used DAC 3 (Front) */
11105 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11106 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11107
11108 { }
11109};
11110
11111static struct hda_verb alc861_threestack_init_verbs[] = {
11112 /*
11113 * Unmute ADC0 and set the default input to mic-in
11114 */
11115 /* port-A for surround (rear panel) */
11116 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11117 /* port-B for mic-in (rear panel) with vref */
11118 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11119 /* port-C for line-in (rear panel) */
11120 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11121 /* port-D for Front */
11122 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11123 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11124 /* port-E for HP out (front panel) */
11125 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11126 /* route front PCM to HP */
9dece1d7 11127 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
11128 /* port-F for mic-in (front panel) with vref */
11129 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11130 /* port-G for CLFE (rear panel) */
11131 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11132 /* port-H for side (rear panel) */
11133 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11134 /* CD-in */
11135 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11136 /* route front mic to ADC1*/
11137 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11138 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11139 /* Unmute DAC0~3 & spdif out*/
11140 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11141 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11142 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11143 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11145
11146 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11147 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11148 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11149 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11150 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11151
11152 /* Unmute Stereo Mixer 15 */
11153 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11154 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11155 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11157
11158 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11159 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11160 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11161 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11162 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11165 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11166 /* hp used DAC 3 (Front) */
11167 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11169 { }
11170};
22309c3e
TI
11171
11172static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11173 /*
11174 * Unmute ADC0 and set the default input to mic-in
11175 */
11176 /* port-A for surround (rear panel) */
11177 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11178 /* port-B for mic-in (rear panel) with vref */
11179 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11180 /* port-C for line-in (rear panel) */
11181 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11182 /* port-D for Front */
11183 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11184 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11185 /* port-E for HP out (front panel) */
f12ab1e0
TI
11186 /* this has to be set to VREF80 */
11187 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 11188 /* route front PCM to HP */
9dece1d7 11189 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
11190 /* port-F for mic-in (front panel) with vref */
11191 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11192 /* port-G for CLFE (rear panel) */
11193 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11194 /* port-H for side (rear panel) */
11195 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11196 /* CD-in */
11197 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11198 /* route front mic to ADC1*/
11199 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11201 /* Unmute DAC0~3 & spdif out*/
11202 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11203 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11204 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11205 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11207
11208 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11209 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11210 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11211 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11212 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11213
11214 /* Unmute Stereo Mixer 15 */
11215 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11216 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11217 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11218 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
11219
11220 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11221 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11222 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11223 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11224 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11225 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11226 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11227 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11228 /* hp used DAC 3 (Front) */
11229 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
11230 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11231 { }
11232};
11233
7cdbff94
MD
11234static struct hda_verb alc861_asus_init_verbs[] = {
11235 /*
11236 * Unmute ADC0 and set the default input to mic-in
11237 */
f12ab1e0
TI
11238 /* port-A for surround (rear panel)
11239 * according to codec#0 this is the HP jack
11240 */
7cdbff94
MD
11241 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11242 /* route front PCM to HP */
11243 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11244 /* port-B for mic-in (rear panel) with vref */
11245 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11246 /* port-C for line-in (rear panel) */
11247 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11248 /* port-D for Front */
11249 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11250 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11251 /* port-E for HP out (front panel) */
f12ab1e0
TI
11252 /* this has to be set to VREF80 */
11253 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 11254 /* route front PCM to HP */
9dece1d7 11255 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
11256 /* port-F for mic-in (front panel) with vref */
11257 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11258 /* port-G for CLFE (rear panel) */
11259 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11260 /* port-H for side (rear panel) */
11261 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11262 /* CD-in */
11263 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11264 /* route front mic to ADC1*/
11265 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11266 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11267 /* Unmute DAC0~3 & spdif out*/
11268 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11269 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11270 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11271 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11273 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11274 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11275 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11276 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11277 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11278
11279 /* Unmute Stereo Mixer 15 */
11280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11281 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11282 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
11284
11285 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11286 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11287 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11288 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11289 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11290 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11291 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11292 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11293 /* hp used DAC 3 (Front) */
11294 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
11295 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11296 { }
11297};
11298
56bb0cab
TI
11299/* additional init verbs for ASUS laptops */
11300static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11301 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11302 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11303 { }
11304};
7cdbff94 11305
df694daa
KY
11306/*
11307 * generic initialization of ADC, input mixers and output mixers
11308 */
11309static struct hda_verb alc861_auto_init_verbs[] = {
11310 /*
11311 * Unmute ADC0 and set the default input to mic-in
11312 */
f12ab1e0 11313 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
11314 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11315
11316 /* Unmute DAC0~3 & spdif out*/
11317 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11318 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11319 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11320 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11322
11323 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11324 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11325 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11326 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11327 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11328
11329 /* Unmute Stereo Mixer 15 */
11330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11334
11335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11336 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11337 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11343
11344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11346 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11347 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11348 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11349 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11350 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11351 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 11352
f12ab1e0 11353 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
11354
11355 { }
11356};
11357
a53d1aec
TD
11358static struct hda_verb alc861_toshiba_init_verbs[] = {
11359 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 11360
a53d1aec
TD
11361 { }
11362};
11363
11364/* toggle speaker-output according to the hp-jack state */
11365static void alc861_toshiba_automute(struct hda_codec *codec)
11366{
11367 unsigned int present;
11368
11369 present = snd_hda_codec_read(codec, 0x0f, 0,
11370 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11371 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11372 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11373 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11374 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
11375}
11376
11377static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11378 unsigned int res)
11379{
a53d1aec
TD
11380 if ((res >> 26) == ALC880_HP_EVENT)
11381 alc861_toshiba_automute(codec);
11382}
11383
df694daa
KY
11384/* pcm configuration: identiacal with ALC880 */
11385#define alc861_pcm_analog_playback alc880_pcm_analog_playback
11386#define alc861_pcm_analog_capture alc880_pcm_analog_capture
11387#define alc861_pcm_digital_playback alc880_pcm_digital_playback
11388#define alc861_pcm_digital_capture alc880_pcm_digital_capture
11389
11390
11391#define ALC861_DIGOUT_NID 0x07
11392
11393static struct hda_channel_mode alc861_8ch_modes[1] = {
11394 { 8, NULL }
11395};
11396
11397static hda_nid_t alc861_dac_nids[4] = {
11398 /* front, surround, clfe, side */
11399 0x03, 0x06, 0x05, 0x04
11400};
11401
9c7f852e
TI
11402static hda_nid_t alc660_dac_nids[3] = {
11403 /* front, clfe, surround */
11404 0x03, 0x05, 0x06
11405};
11406
df694daa
KY
11407static hda_nid_t alc861_adc_nids[1] = {
11408 /* ADC0-2 */
11409 0x08,
11410};
11411
11412static struct hda_input_mux alc861_capture_source = {
11413 .num_items = 5,
11414 .items = {
11415 { "Mic", 0x0 },
11416 { "Front Mic", 0x3 },
11417 { "Line", 0x1 },
11418 { "CD", 0x4 },
11419 { "Mixer", 0x5 },
11420 },
11421};
11422
11423/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
11424static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11425 const struct auto_pin_cfg *cfg)
df694daa
KY
11426{
11427 int i;
11428 hda_nid_t nid;
11429
11430 spec->multiout.dac_nids = spec->private_dac_nids;
11431 for (i = 0; i < cfg->line_outs; i++) {
11432 nid = cfg->line_out_pins[i];
11433 if (nid) {
11434 if (i >= ARRAY_SIZE(alc861_dac_nids))
11435 continue;
11436 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11437 }
11438 }
11439 spec->multiout.num_dacs = cfg->line_outs;
11440 return 0;
11441}
11442
11443/* add playback controls from the parsed DAC table */
11444static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11445 const struct auto_pin_cfg *cfg)
11446{
11447 char name[32];
f12ab1e0
TI
11448 static const char *chname[4] = {
11449 "Front", "Surround", NULL /*CLFE*/, "Side"
11450 };
df694daa
KY
11451 hda_nid_t nid;
11452 int i, idx, err;
11453
11454 for (i = 0; i < cfg->line_outs; i++) {
11455 nid = spec->multiout.dac_nids[i];
f12ab1e0 11456 if (!nid)
df694daa
KY
11457 continue;
11458 if (nid == 0x05) {
11459 /* Center/LFE */
f12ab1e0
TI
11460 err = add_control(spec, ALC_CTL_BIND_MUTE,
11461 "Center Playback Switch",
11462 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11463 HDA_OUTPUT));
11464 if (err < 0)
df694daa 11465 return err;
f12ab1e0
TI
11466 err = add_control(spec, ALC_CTL_BIND_MUTE,
11467 "LFE Playback Switch",
11468 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11469 HDA_OUTPUT));
11470 if (err < 0)
df694daa
KY
11471 return err;
11472 } else {
f12ab1e0
TI
11473 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11474 idx++)
df694daa
KY
11475 if (nid == alc861_dac_nids[idx])
11476 break;
11477 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
11478 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11479 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11480 HDA_OUTPUT));
11481 if (err < 0)
df694daa
KY
11482 return err;
11483 }
11484 }
11485 return 0;
11486}
11487
11488static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11489{
11490 int err;
11491 hda_nid_t nid;
11492
f12ab1e0 11493 if (!pin)
df694daa
KY
11494 return 0;
11495
11496 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11497 nid = 0x03;
f12ab1e0
TI
11498 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11499 "Headphone Playback Switch",
11500 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11501 if (err < 0)
df694daa
KY
11502 return err;
11503 spec->multiout.hp_nid = nid;
11504 }
11505 return 0;
11506}
11507
11508/* create playback/capture controls for input pins */
f12ab1e0
TI
11509static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11510 const struct auto_pin_cfg *cfg)
df694daa 11511{
df694daa
KY
11512 struct hda_input_mux *imux = &spec->private_imux;
11513 int i, err, idx, idx1;
11514
11515 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 11516 switch (cfg->input_pins[i]) {
df694daa
KY
11517 case 0x0c:
11518 idx1 = 1;
f12ab1e0 11519 idx = 2; /* Line In */
df694daa
KY
11520 break;
11521 case 0x0f:
11522 idx1 = 2;
f12ab1e0 11523 idx = 2; /* Line In */
df694daa
KY
11524 break;
11525 case 0x0d:
11526 idx1 = 0;
f12ab1e0 11527 idx = 1; /* Mic In */
df694daa 11528 break;
f12ab1e0 11529 case 0x10:
df694daa 11530 idx1 = 3;
f12ab1e0 11531 idx = 1; /* Mic In */
df694daa
KY
11532 break;
11533 case 0x11:
11534 idx1 = 4;
f12ab1e0 11535 idx = 0; /* CD */
df694daa
KY
11536 break;
11537 default:
11538 continue;
11539 }
11540
4a471b7d
TI
11541 err = new_analog_input(spec, cfg->input_pins[i],
11542 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
11543 if (err < 0)
11544 return err;
11545
4a471b7d 11546 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 11547 imux->items[imux->num_items].index = idx1;
f12ab1e0 11548 imux->num_items++;
df694daa
KY
11549 }
11550 return 0;
11551}
11552
11553static struct snd_kcontrol_new alc861_capture_mixer[] = {
11554 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11555 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11556
11557 {
11558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11559 /* The multiple "Capture Source" controls confuse alsamixer
11560 * So call somewhat different..
df694daa
KY
11561 */
11562 /* .name = "Capture Source", */
11563 .name = "Input Source",
11564 .count = 1,
11565 .info = alc_mux_enum_info,
11566 .get = alc_mux_enum_get,
11567 .put = alc_mux_enum_put,
11568 },
11569 { } /* end */
11570};
11571
f12ab1e0
TI
11572static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11573 hda_nid_t nid,
df694daa
KY
11574 int pin_type, int dac_idx)
11575{
f6c7e546 11576 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
11577}
11578
11579static void alc861_auto_init_multi_out(struct hda_codec *codec)
11580{
11581 struct alc_spec *spec = codec->spec;
11582 int i;
11583
bc9f98a9 11584 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
11585 for (i = 0; i < spec->autocfg.line_outs; i++) {
11586 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11587 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 11588 if (nid)
baba8ee9 11589 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 11590 spec->multiout.dac_nids[i]);
df694daa
KY
11591 }
11592}
11593
11594static void alc861_auto_init_hp_out(struct hda_codec *codec)
11595{
11596 struct alc_spec *spec = codec->spec;
11597 hda_nid_t pin;
11598
eb06ed8f 11599 pin = spec->autocfg.hp_pins[0];
df694daa 11600 if (pin) /* connect to front */
f12ab1e0
TI
11601 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11602 spec->multiout.dac_nids[0]);
f6c7e546
TI
11603 pin = spec->autocfg.speaker_pins[0];
11604 if (pin)
11605 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
11606}
11607
11608static void alc861_auto_init_analog_input(struct hda_codec *codec)
11609{
11610 struct alc_spec *spec = codec->spec;
11611 int i;
11612
11613 for (i = 0; i < AUTO_PIN_LAST; i++) {
11614 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
11615 if (nid >= 0x0c && nid <= 0x11) {
11616 snd_hda_codec_write(codec, nid, 0,
11617 AC_VERB_SET_PIN_WIDGET_CONTROL,
11618 i <= AUTO_PIN_FRONT_MIC ?
11619 PIN_VREF80 : PIN_IN);
df694daa
KY
11620 }
11621 }
11622}
11623
11624/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
11625/* return 1 if successful, 0 if the proper config is not found,
11626 * or a negative error code
11627 */
df694daa
KY
11628static int alc861_parse_auto_config(struct hda_codec *codec)
11629{
11630 struct alc_spec *spec = codec->spec;
11631 int err;
11632 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11633
f12ab1e0
TI
11634 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11635 alc861_ignore);
11636 if (err < 0)
df694daa 11637 return err;
f12ab1e0 11638 if (!spec->autocfg.line_outs)
df694daa
KY
11639 return 0; /* can't find valid BIOS pin config */
11640
f12ab1e0
TI
11641 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11642 if (err < 0)
11643 return err;
11644 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11645 if (err < 0)
11646 return err;
11647 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11648 if (err < 0)
11649 return err;
11650 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11651 if (err < 0)
df694daa
KY
11652 return err;
11653
11654 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11655
11656 if (spec->autocfg.dig_out_pin)
11657 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11658
11659 if (spec->kctl_alloc)
11660 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11661
11662 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11663
a1e8d2da 11664 spec->num_mux_defs = 1;
df694daa
KY
11665 spec->input_mux = &spec->private_imux;
11666
11667 spec->adc_nids = alc861_adc_nids;
11668 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11669 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11670 spec->num_mixers++;
11671
11672 return 1;
11673}
11674
ae6b813a
TI
11675/* additional initialization for auto-configuration model */
11676static void alc861_auto_init(struct hda_codec *codec)
df694daa 11677{
f6c7e546 11678 struct alc_spec *spec = codec->spec;
df694daa
KY
11679 alc861_auto_init_multi_out(codec);
11680 alc861_auto_init_hp_out(codec);
11681 alc861_auto_init_analog_input(codec);
f6c7e546
TI
11682 if (spec->unsol_event)
11683 alc_sku_automute(codec);
df694daa
KY
11684}
11685
cb53c626
TI
11686#ifdef CONFIG_SND_HDA_POWER_SAVE
11687static struct hda_amp_list alc861_loopbacks[] = {
11688 { 0x15, HDA_INPUT, 0 },
11689 { 0x15, HDA_INPUT, 1 },
11690 { 0x15, HDA_INPUT, 2 },
11691 { 0x15, HDA_INPUT, 3 },
11692 { } /* end */
11693};
11694#endif
11695
df694daa
KY
11696
11697/*
11698 * configuration and preset
11699 */
f5fcc13c
TI
11700static const char *alc861_models[ALC861_MODEL_LAST] = {
11701 [ALC861_3ST] = "3stack",
11702 [ALC660_3ST] = "3stack-660",
11703 [ALC861_3ST_DIG] = "3stack-dig",
11704 [ALC861_6ST_DIG] = "6stack-dig",
11705 [ALC861_UNIWILL_M31] = "uniwill-m31",
11706 [ALC861_TOSHIBA] = "toshiba",
11707 [ALC861_ASUS] = "asus",
11708 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11709 [ALC861_AUTO] = "auto",
11710};
11711
11712static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 11713 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
11714 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11715 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11716 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 11717 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 11718 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 11719 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
11720 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11721 * Any other models that need this preset?
11722 */
11723 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
11724 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11725 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 11726 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
11727 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11728 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11729 /* FIXME: the below seems conflict */
11730 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 11731 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 11732 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
11733 {}
11734};
11735
11736static struct alc_config_preset alc861_presets[] = {
11737 [ALC861_3ST] = {
11738 .mixers = { alc861_3ST_mixer },
11739 .init_verbs = { alc861_threestack_init_verbs },
11740 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11741 .dac_nids = alc861_dac_nids,
11742 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11743 .channel_mode = alc861_threestack_modes,
4e195a7b 11744 .need_dac_fix = 1,
df694daa
KY
11745 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11746 .adc_nids = alc861_adc_nids,
11747 .input_mux = &alc861_capture_source,
11748 },
11749 [ALC861_3ST_DIG] = {
11750 .mixers = { alc861_base_mixer },
11751 .init_verbs = { alc861_threestack_init_verbs },
11752 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11753 .dac_nids = alc861_dac_nids,
11754 .dig_out_nid = ALC861_DIGOUT_NID,
11755 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11756 .channel_mode = alc861_threestack_modes,
4e195a7b 11757 .need_dac_fix = 1,
df694daa
KY
11758 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11759 .adc_nids = alc861_adc_nids,
11760 .input_mux = &alc861_capture_source,
11761 },
11762 [ALC861_6ST_DIG] = {
11763 .mixers = { alc861_base_mixer },
11764 .init_verbs = { alc861_base_init_verbs },
11765 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11766 .dac_nids = alc861_dac_nids,
11767 .dig_out_nid = ALC861_DIGOUT_NID,
11768 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11769 .channel_mode = alc861_8ch_modes,
11770 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11771 .adc_nids = alc861_adc_nids,
11772 .input_mux = &alc861_capture_source,
11773 },
9c7f852e
TI
11774 [ALC660_3ST] = {
11775 .mixers = { alc861_3ST_mixer },
11776 .init_verbs = { alc861_threestack_init_verbs },
11777 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11778 .dac_nids = alc660_dac_nids,
11779 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11780 .channel_mode = alc861_threestack_modes,
4e195a7b 11781 .need_dac_fix = 1,
9c7f852e
TI
11782 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11783 .adc_nids = alc861_adc_nids,
11784 .input_mux = &alc861_capture_source,
11785 },
22309c3e
TI
11786 [ALC861_UNIWILL_M31] = {
11787 .mixers = { alc861_uniwill_m31_mixer },
11788 .init_verbs = { alc861_uniwill_m31_init_verbs },
11789 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11790 .dac_nids = alc861_dac_nids,
11791 .dig_out_nid = ALC861_DIGOUT_NID,
11792 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11793 .channel_mode = alc861_uniwill_m31_modes,
11794 .need_dac_fix = 1,
11795 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11796 .adc_nids = alc861_adc_nids,
11797 .input_mux = &alc861_capture_source,
11798 },
a53d1aec
TD
11799 [ALC861_TOSHIBA] = {
11800 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
11801 .init_verbs = { alc861_base_init_verbs,
11802 alc861_toshiba_init_verbs },
a53d1aec
TD
11803 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11804 .dac_nids = alc861_dac_nids,
11805 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11806 .channel_mode = alc883_3ST_2ch_modes,
11807 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11808 .adc_nids = alc861_adc_nids,
11809 .input_mux = &alc861_capture_source,
11810 .unsol_event = alc861_toshiba_unsol_event,
11811 .init_hook = alc861_toshiba_automute,
11812 },
7cdbff94
MD
11813 [ALC861_ASUS] = {
11814 .mixers = { alc861_asus_mixer },
11815 .init_verbs = { alc861_asus_init_verbs },
11816 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11817 .dac_nids = alc861_dac_nids,
11818 .dig_out_nid = ALC861_DIGOUT_NID,
11819 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11820 .channel_mode = alc861_asus_modes,
11821 .need_dac_fix = 1,
11822 .hp_nid = 0x06,
11823 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11824 .adc_nids = alc861_adc_nids,
11825 .input_mux = &alc861_capture_source,
11826 },
56bb0cab
TI
11827 [ALC861_ASUS_LAPTOP] = {
11828 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11829 .init_verbs = { alc861_asus_init_verbs,
11830 alc861_asus_laptop_init_verbs },
11831 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11832 .dac_nids = alc861_dac_nids,
11833 .dig_out_nid = ALC861_DIGOUT_NID,
11834 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11835 .channel_mode = alc883_3ST_2ch_modes,
11836 .need_dac_fix = 1,
11837 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11838 .adc_nids = alc861_adc_nids,
11839 .input_mux = &alc861_capture_source,
11840 },
11841};
df694daa
KY
11842
11843
11844static int patch_alc861(struct hda_codec *codec)
11845{
11846 struct alc_spec *spec;
11847 int board_config;
11848 int err;
11849
dc041e0b 11850 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11851 if (spec == NULL)
11852 return -ENOMEM;
11853
f12ab1e0 11854 codec->spec = spec;
df694daa 11855
f5fcc13c
TI
11856 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11857 alc861_models,
11858 alc861_cfg_tbl);
9c7f852e 11859
f5fcc13c 11860 if (board_config < 0) {
9c7f852e
TI
11861 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11862 "trying auto-probe from BIOS...\n");
df694daa
KY
11863 board_config = ALC861_AUTO;
11864 }
11865
11866 if (board_config == ALC861_AUTO) {
11867 /* automatic parse from the BIOS config */
11868 err = alc861_parse_auto_config(codec);
11869 if (err < 0) {
11870 alc_free(codec);
11871 return err;
f12ab1e0 11872 } else if (!err) {
9c7f852e
TI
11873 printk(KERN_INFO
11874 "hda_codec: Cannot set up configuration "
11875 "from BIOS. Using base mode...\n");
df694daa
KY
11876 board_config = ALC861_3ST_DIG;
11877 }
11878 }
11879
11880 if (board_config != ALC861_AUTO)
11881 setup_preset(spec, &alc861_presets[board_config]);
11882
11883 spec->stream_name_analog = "ALC861 Analog";
11884 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11885 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11886
11887 spec->stream_name_digital = "ALC861 Digital";
11888 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11889 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11890
2134ea4f
TI
11891 spec->vmaster_nid = 0x03;
11892
df694daa
KY
11893 codec->patch_ops = alc_patch_ops;
11894 if (board_config == ALC861_AUTO)
ae6b813a 11895 spec->init_hook = alc861_auto_init;
cb53c626
TI
11896#ifdef CONFIG_SND_HDA_POWER_SAVE
11897 if (!spec->loopback.amplist)
11898 spec->loopback.amplist = alc861_loopbacks;
11899#endif
df694daa 11900
1da177e4
LT
11901 return 0;
11902}
11903
f32610ed
JS
11904/*
11905 * ALC861-VD support
11906 *
11907 * Based on ALC882
11908 *
11909 * In addition, an independent DAC
11910 */
11911#define ALC861VD_DIGOUT_NID 0x06
11912
11913static hda_nid_t alc861vd_dac_nids[4] = {
11914 /* front, surr, clfe, side surr */
11915 0x02, 0x03, 0x04, 0x05
11916};
11917
11918/* dac_nids for ALC660vd are in a different order - according to
11919 * Realtek's driver.
11920 * This should probably tesult in a different mixer for 6stack models
11921 * of ALC660vd codecs, but for now there is only 3stack mixer
11922 * - and it is the same as in 861vd.
11923 * adc_nids in ALC660vd are (is) the same as in 861vd
11924 */
11925static hda_nid_t alc660vd_dac_nids[3] = {
11926 /* front, rear, clfe, rear_surr */
11927 0x02, 0x04, 0x03
11928};
11929
11930static hda_nid_t alc861vd_adc_nids[1] = {
11931 /* ADC0 */
11932 0x09,
11933};
11934
e1406348
TI
11935static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
11936
f32610ed
JS
11937/* input MUX */
11938/* FIXME: should be a matrix-type input source selection */
11939static struct hda_input_mux alc861vd_capture_source = {
11940 .num_items = 4,
11941 .items = {
11942 { "Mic", 0x0 },
11943 { "Front Mic", 0x1 },
11944 { "Line", 0x2 },
11945 { "CD", 0x4 },
11946 },
11947};
11948
272a527c
KY
11949static struct hda_input_mux alc861vd_dallas_capture_source = {
11950 .num_items = 3,
11951 .items = {
11952 { "Front Mic", 0x0 },
11953 { "ATAPI Mic", 0x1 },
11954 { "Line In", 0x5 },
11955 },
11956};
11957
d1a991a6
KY
11958static struct hda_input_mux alc861vd_hp_capture_source = {
11959 .num_items = 2,
11960 .items = {
11961 { "Front Mic", 0x0 },
11962 { "ATAPI Mic", 0x1 },
11963 },
11964};
11965
f32610ed
JS
11966#define alc861vd_mux_enum_info alc_mux_enum_info
11967#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
11968/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
11969#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
11970
11971/*
11972 * 2ch mode
11973 */
11974static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11975 { 2, NULL }
11976};
11977
11978/*
11979 * 6ch mode
11980 */
11981static struct hda_verb alc861vd_6stack_ch6_init[] = {
11982 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11983 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11984 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11985 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11986 { } /* end */
11987};
11988
11989/*
11990 * 8ch mode
11991 */
11992static struct hda_verb alc861vd_6stack_ch8_init[] = {
11993 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11994 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11995 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11996 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11997 { } /* end */
11998};
11999
12000static struct hda_channel_mode alc861vd_6stack_modes[2] = {
12001 { 6, alc861vd_6stack_ch6_init },
12002 { 8, alc861vd_6stack_ch8_init },
12003};
12004
12005static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
12006 {
12007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12008 .name = "Channel Mode",
12009 .info = alc_ch_mode_info,
12010 .get = alc_ch_mode_get,
12011 .put = alc_ch_mode_put,
12012 },
12013 { } /* end */
12014};
12015
12016static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
12017 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12018 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12019
12020 {
12021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12022 /* The multiple "Capture Source" controls confuse alsamixer
12023 * So call somewhat different..
f32610ed
JS
12024 */
12025 /* .name = "Capture Source", */
12026 .name = "Input Source",
12027 .count = 1,
12028 .info = alc861vd_mux_enum_info,
12029 .get = alc861vd_mux_enum_get,
12030 .put = alc861vd_mux_enum_put,
12031 },
12032 { } /* end */
12033};
12034
12035/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12036 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12037 */
12038static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
12039 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12040 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12041
12042 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12043 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
12044
12045 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
12046 HDA_OUTPUT),
12047 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
12048 HDA_OUTPUT),
12049 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12050 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
12051
12052 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
12053 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
12054
12055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12056
12057 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12058 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12059 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12060
12061 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12062 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12063 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12064
12065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12067
12068 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12069 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12070
12071 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12072 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12073
12074 { } /* end */
12075};
12076
12077static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12078 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12079 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12080
12081 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12082
12083 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12086
12087 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12088 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12089 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12090
12091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12093
12094 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12095 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12096
12097 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12098 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12099
12100 { } /* end */
12101};
12102
bdd148a3
KY
12103static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12104 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12105 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12106 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12107
12108 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12109
12110 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12113
12114 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12117
12118 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12119 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12120
12121 { } /* end */
12122};
12123
272a527c
KY
12124/* Pin assignment: Front=0x14, HP = 0x15,
12125 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
12126 */
12127static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12128 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12129 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12130 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12131 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12132 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12133 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12134 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12135 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
12137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
12138 { } /* end */
12139};
12140
d1a991a6
KY
12141/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12142 * Front Mic=0x18, ATAPI Mic = 0x19,
12143 */
12144static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12145 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12146 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12147 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12148 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12149 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12151 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12152 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12153
12154 { } /* end */
12155};
12156
f32610ed
JS
12157/*
12158 * generic initialization of ADC, input mixers and output mixers
12159 */
12160static struct hda_verb alc861vd_volume_init_verbs[] = {
12161 /*
12162 * Unmute ADC0 and set the default input to mic-in
12163 */
12164 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12165 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12166
12167 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12168 * the analog-loopback mixer widget
12169 */
12170 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12175 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
12176
12177 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
12178 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 12181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
12182
12183 /*
12184 * Set up output mixers (0x02 - 0x05)
12185 */
12186 /* set vol=0 to output mixers */
12187 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12188 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12189 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12190 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12191
12192 /* set up input amps for analog loopback */
12193 /* Amp Indices: DAC = 0, mixer = 1 */
12194 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12196 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12201 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12202
12203 { }
12204};
12205
12206/*
12207 * 3-stack pin configuration:
12208 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12209 */
12210static struct hda_verb alc861vd_3stack_init_verbs[] = {
12211 /*
12212 * Set pin mode and muting
12213 */
12214 /* set front pin widgets 0x14 for output */
12215 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12217 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12218
12219 /* Mic (rear) pin: input vref at 80% */
12220 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12221 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12222 /* Front Mic pin: input vref at 80% */
12223 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12224 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12225 /* Line In pin: input */
12226 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12227 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12228 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12229 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12230 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12231 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12232 /* CD pin widget for input */
12233 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12234
12235 { }
12236};
12237
12238/*
12239 * 6-stack pin configuration:
12240 */
12241static struct hda_verb alc861vd_6stack_init_verbs[] = {
12242 /*
12243 * Set pin mode and muting
12244 */
12245 /* set front pin widgets 0x14 for output */
12246 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12247 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12248 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12249
12250 /* Rear Pin: output 1 (0x0d) */
12251 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12252 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12253 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12254 /* CLFE Pin: output 2 (0x0e) */
12255 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12256 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12257 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12258 /* Side Pin: output 3 (0x0f) */
12259 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12260 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12261 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12262
12263 /* Mic (rear) pin: input vref at 80% */
12264 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12265 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12266 /* Front Mic pin: input vref at 80% */
12267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12269 /* Line In pin: input */
12270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12271 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12272 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12274 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12275 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12276 /* CD pin widget for input */
12277 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12278
12279 { }
12280};
12281
bdd148a3
KY
12282static struct hda_verb alc861vd_eapd_verbs[] = {
12283 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12284 { }
12285};
12286
12287static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12291 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12292 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12293 {}
12294};
12295
12296/* toggle speaker-output according to the hp-jack state */
12297static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12298{
12299 unsigned int present;
12300 unsigned char bits;
12301
12302 present = snd_hda_codec_read(codec, 0x1b, 0,
12303 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12304 bits = present ? HDA_AMP_MUTE : 0;
12305 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12306 HDA_AMP_MUTE, bits);
bdd148a3
KY
12307}
12308
12309static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12310{
12311 unsigned int present;
12312 unsigned char bits;
12313
12314 present = snd_hda_codec_read(codec, 0x18, 0,
12315 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12316 bits = present ? HDA_AMP_MUTE : 0;
12317 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12318 HDA_AMP_MUTE, bits);
bdd148a3
KY
12319}
12320
12321static void alc861vd_lenovo_automute(struct hda_codec *codec)
12322{
12323 alc861vd_lenovo_hp_automute(codec);
12324 alc861vd_lenovo_mic_automute(codec);
12325}
12326
12327static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12328 unsigned int res)
12329{
12330 switch (res >> 26) {
12331 case ALC880_HP_EVENT:
12332 alc861vd_lenovo_hp_automute(codec);
12333 break;
12334 case ALC880_MIC_EVENT:
12335 alc861vd_lenovo_mic_automute(codec);
12336 break;
12337 }
12338}
12339
272a527c
KY
12340static struct hda_verb alc861vd_dallas_verbs[] = {
12341 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12342 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12343 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12344 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12345
12346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12347 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12348 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12349 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12350 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12351 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12353 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12354
12355 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12356 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12357 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12358 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12359 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12360 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12361 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12362 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12363
12364 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12365 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12366 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12367 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12368 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12370 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12371 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12372
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12377
12378 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12379 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12380 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12381
12382 { } /* end */
12383};
12384
12385/* toggle speaker-output according to the hp-jack state */
12386static void alc861vd_dallas_automute(struct hda_codec *codec)
12387{
12388 unsigned int present;
12389
12390 present = snd_hda_codec_read(codec, 0x15, 0,
12391 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12392 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12393 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
12394}
12395
12396static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12397{
12398 if ((res >> 26) == ALC880_HP_EVENT)
12399 alc861vd_dallas_automute(codec);
12400}
12401
cb53c626
TI
12402#ifdef CONFIG_SND_HDA_POWER_SAVE
12403#define alc861vd_loopbacks alc880_loopbacks
12404#endif
12405
f32610ed
JS
12406/* pcm configuration: identiacal with ALC880 */
12407#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12408#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12409#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12410#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12411
12412/*
12413 * configuration and preset
12414 */
12415static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12416 [ALC660VD_3ST] = "3stack-660",
983f8ae4 12417 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
12418 [ALC861VD_3ST] = "3stack",
12419 [ALC861VD_3ST_DIG] = "3stack-digout",
12420 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 12421 [ALC861VD_LENOVO] = "lenovo",
272a527c 12422 [ALC861VD_DALLAS] = "dallas",
983f8ae4 12423 [ALC861VD_HP] = "hp",
f32610ed
JS
12424 [ALC861VD_AUTO] = "auto",
12425};
12426
12427static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
12428 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12429 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 12430 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 12431 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 12432 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 12433 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 12434 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 12435 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 12436 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 12437 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
39c5d41f 12438 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
12439 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12440 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 12441 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
12442 {}
12443};
12444
12445static struct alc_config_preset alc861vd_presets[] = {
12446 [ALC660VD_3ST] = {
12447 .mixers = { alc861vd_3st_mixer },
12448 .init_verbs = { alc861vd_volume_init_verbs,
12449 alc861vd_3stack_init_verbs },
12450 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12451 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
12452 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12453 .channel_mode = alc861vd_3stack_2ch_modes,
12454 .input_mux = &alc861vd_capture_source,
12455 },
6963f84c
MC
12456 [ALC660VD_3ST_DIG] = {
12457 .mixers = { alc861vd_3st_mixer },
12458 .init_verbs = { alc861vd_volume_init_verbs,
12459 alc861vd_3stack_init_verbs },
12460 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12461 .dac_nids = alc660vd_dac_nids,
12462 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
12463 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12464 .channel_mode = alc861vd_3stack_2ch_modes,
12465 .input_mux = &alc861vd_capture_source,
12466 },
f32610ed
JS
12467 [ALC861VD_3ST] = {
12468 .mixers = { alc861vd_3st_mixer },
12469 .init_verbs = { alc861vd_volume_init_verbs,
12470 alc861vd_3stack_init_verbs },
12471 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12472 .dac_nids = alc861vd_dac_nids,
12473 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12474 .channel_mode = alc861vd_3stack_2ch_modes,
12475 .input_mux = &alc861vd_capture_source,
12476 },
12477 [ALC861VD_3ST_DIG] = {
12478 .mixers = { alc861vd_3st_mixer },
12479 .init_verbs = { alc861vd_volume_init_verbs,
12480 alc861vd_3stack_init_verbs },
12481 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12482 .dac_nids = alc861vd_dac_nids,
12483 .dig_out_nid = ALC861VD_DIGOUT_NID,
12484 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12485 .channel_mode = alc861vd_3stack_2ch_modes,
12486 .input_mux = &alc861vd_capture_source,
12487 },
12488 [ALC861VD_6ST_DIG] = {
12489 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12490 .init_verbs = { alc861vd_volume_init_verbs,
12491 alc861vd_6stack_init_verbs },
12492 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12493 .dac_nids = alc861vd_dac_nids,
12494 .dig_out_nid = ALC861VD_DIGOUT_NID,
12495 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12496 .channel_mode = alc861vd_6stack_modes,
12497 .input_mux = &alc861vd_capture_source,
12498 },
bdd148a3
KY
12499 [ALC861VD_LENOVO] = {
12500 .mixers = { alc861vd_lenovo_mixer },
12501 .init_verbs = { alc861vd_volume_init_verbs,
12502 alc861vd_3stack_init_verbs,
12503 alc861vd_eapd_verbs,
12504 alc861vd_lenovo_unsol_verbs },
12505 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12506 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
12507 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12508 .channel_mode = alc861vd_3stack_2ch_modes,
12509 .input_mux = &alc861vd_capture_source,
12510 .unsol_event = alc861vd_lenovo_unsol_event,
12511 .init_hook = alc861vd_lenovo_automute,
12512 },
272a527c
KY
12513 [ALC861VD_DALLAS] = {
12514 .mixers = { alc861vd_dallas_mixer },
12515 .init_verbs = { alc861vd_dallas_verbs },
12516 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12517 .dac_nids = alc861vd_dac_nids,
272a527c
KY
12518 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12519 .channel_mode = alc861vd_3stack_2ch_modes,
12520 .input_mux = &alc861vd_dallas_capture_source,
12521 .unsol_event = alc861vd_dallas_unsol_event,
12522 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
12523 },
12524 [ALC861VD_HP] = {
12525 .mixers = { alc861vd_hp_mixer },
12526 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12527 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12528 .dac_nids = alc861vd_dac_nids,
d1a991a6 12529 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
12530 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12531 .channel_mode = alc861vd_3stack_2ch_modes,
12532 .input_mux = &alc861vd_hp_capture_source,
12533 .unsol_event = alc861vd_dallas_unsol_event,
12534 .init_hook = alc861vd_dallas_automute,
12535 },
f32610ed
JS
12536};
12537
12538/*
12539 * BIOS auto configuration
12540 */
12541static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12542 hda_nid_t nid, int pin_type, int dac_idx)
12543{
f6c7e546 12544 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
12545}
12546
12547static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12548{
12549 struct alc_spec *spec = codec->spec;
12550 int i;
12551
bc9f98a9 12552 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
12553 for (i = 0; i <= HDA_SIDE; i++) {
12554 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 12555 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
12556 if (nid)
12557 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 12558 pin_type, i);
f32610ed
JS
12559 }
12560}
12561
12562
12563static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12564{
12565 struct alc_spec *spec = codec->spec;
12566 hda_nid_t pin;
12567
12568 pin = spec->autocfg.hp_pins[0];
12569 if (pin) /* connect to front and use dac 0 */
12570 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
12571 pin = spec->autocfg.speaker_pins[0];
12572 if (pin)
12573 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
12574}
12575
12576#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12577#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12578
12579static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12580{
12581 struct alc_spec *spec = codec->spec;
12582 int i;
12583
12584 for (i = 0; i < AUTO_PIN_LAST; i++) {
12585 hda_nid_t nid = spec->autocfg.input_pins[i];
12586 if (alc861vd_is_input_pin(nid)) {
12587 snd_hda_codec_write(codec, nid, 0,
12588 AC_VERB_SET_PIN_WIDGET_CONTROL,
12589 i <= AUTO_PIN_FRONT_MIC ?
12590 PIN_VREF80 : PIN_IN);
12591 if (nid != ALC861VD_PIN_CD_NID)
12592 snd_hda_codec_write(codec, nid, 0,
12593 AC_VERB_SET_AMP_GAIN_MUTE,
12594 AMP_OUT_MUTE);
12595 }
12596 }
12597}
12598
12599#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12600#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12601
12602/* add playback controls from the parsed DAC table */
12603/* Based on ALC880 version. But ALC861VD has separate,
12604 * different NIDs for mute/unmute switch and volume control */
12605static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12606 const struct auto_pin_cfg *cfg)
12607{
12608 char name[32];
12609 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12610 hda_nid_t nid_v, nid_s;
12611 int i, err;
12612
12613 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 12614 if (!spec->multiout.dac_nids[i])
f32610ed
JS
12615 continue;
12616 nid_v = alc861vd_idx_to_mixer_vol(
12617 alc880_dac_to_idx(
12618 spec->multiout.dac_nids[i]));
12619 nid_s = alc861vd_idx_to_mixer_switch(
12620 alc880_dac_to_idx(
12621 spec->multiout.dac_nids[i]));
12622
12623 if (i == 2) {
12624 /* Center/LFE */
f12ab1e0
TI
12625 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12626 "Center Playback Volume",
12627 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12628 HDA_OUTPUT));
12629 if (err < 0)
f32610ed 12630 return err;
f12ab1e0
TI
12631 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12632 "LFE Playback Volume",
12633 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12634 HDA_OUTPUT));
12635 if (err < 0)
f32610ed 12636 return err;
f12ab1e0
TI
12637 err = add_control(spec, ALC_CTL_BIND_MUTE,
12638 "Center Playback Switch",
12639 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12640 HDA_INPUT));
12641 if (err < 0)
f32610ed 12642 return err;
f12ab1e0
TI
12643 err = add_control(spec, ALC_CTL_BIND_MUTE,
12644 "LFE Playback Switch",
12645 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12646 HDA_INPUT));
12647 if (err < 0)
f32610ed
JS
12648 return err;
12649 } else {
12650 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
12651 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12652 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12653 HDA_OUTPUT));
12654 if (err < 0)
f32610ed
JS
12655 return err;
12656 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 12657 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 12658 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
12659 HDA_INPUT));
12660 if (err < 0)
f32610ed
JS
12661 return err;
12662 }
12663 }
12664 return 0;
12665}
12666
12667/* add playback controls for speaker and HP outputs */
12668/* Based on ALC880 version. But ALC861VD has separate,
12669 * different NIDs for mute/unmute switch and volume control */
12670static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12671 hda_nid_t pin, const char *pfx)
12672{
12673 hda_nid_t nid_v, nid_s;
12674 int err;
12675 char name[32];
12676
f12ab1e0 12677 if (!pin)
f32610ed
JS
12678 return 0;
12679
12680 if (alc880_is_fixed_pin(pin)) {
12681 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12682 /* specify the DAC as the extra output */
f12ab1e0 12683 if (!spec->multiout.hp_nid)
f32610ed
JS
12684 spec->multiout.hp_nid = nid_v;
12685 else
12686 spec->multiout.extra_out_nid[0] = nid_v;
12687 /* control HP volume/switch on the output mixer amp */
12688 nid_v = alc861vd_idx_to_mixer_vol(
12689 alc880_fixed_pin_idx(pin));
12690 nid_s = alc861vd_idx_to_mixer_switch(
12691 alc880_fixed_pin_idx(pin));
12692
12693 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
12694 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12695 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12696 if (err < 0)
f32610ed
JS
12697 return err;
12698 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12699 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12700 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12701 if (err < 0)
f32610ed
JS
12702 return err;
12703 } else if (alc880_is_multi_pin(pin)) {
12704 /* set manual connection */
12705 /* we have only a switch on HP-out PIN */
12706 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12707 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12708 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12709 if (err < 0)
f32610ed
JS
12710 return err;
12711 }
12712 return 0;
12713}
12714
12715/* parse the BIOS configuration and set up the alc_spec
12716 * return 1 if successful, 0 if the proper config is not found,
12717 * or a negative error code
12718 * Based on ALC880 version - had to change it to override
12719 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12720static int alc861vd_parse_auto_config(struct hda_codec *codec)
12721{
12722 struct alc_spec *spec = codec->spec;
12723 int err;
12724 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12725
f12ab1e0
TI
12726 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12727 alc861vd_ignore);
12728 if (err < 0)
f32610ed 12729 return err;
f12ab1e0 12730 if (!spec->autocfg.line_outs)
f32610ed
JS
12731 return 0; /* can't find valid BIOS pin config */
12732
f12ab1e0
TI
12733 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12734 if (err < 0)
12735 return err;
12736 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12737 if (err < 0)
12738 return err;
12739 err = alc861vd_auto_create_extra_out(spec,
12740 spec->autocfg.speaker_pins[0],
12741 "Speaker");
12742 if (err < 0)
12743 return err;
12744 err = alc861vd_auto_create_extra_out(spec,
12745 spec->autocfg.hp_pins[0],
12746 "Headphone");
12747 if (err < 0)
12748 return err;
12749 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12750 if (err < 0)
f32610ed
JS
12751 return err;
12752
12753 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12754
12755 if (spec->autocfg.dig_out_pin)
12756 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12757
12758 if (spec->kctl_alloc)
12759 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12760
12761 spec->init_verbs[spec->num_init_verbs++]
12762 = alc861vd_volume_init_verbs;
12763
12764 spec->num_mux_defs = 1;
12765 spec->input_mux = &spec->private_imux;
12766
776e184e
TI
12767 err = alc_auto_add_mic_boost(codec);
12768 if (err < 0)
12769 return err;
12770
f32610ed
JS
12771 return 1;
12772}
12773
12774/* additional initialization for auto-configuration model */
12775static void alc861vd_auto_init(struct hda_codec *codec)
12776{
f6c7e546 12777 struct alc_spec *spec = codec->spec;
f32610ed
JS
12778 alc861vd_auto_init_multi_out(codec);
12779 alc861vd_auto_init_hp_out(codec);
12780 alc861vd_auto_init_analog_input(codec);
f6c7e546
TI
12781 if (spec->unsol_event)
12782 alc_sku_automute(codec);
f32610ed
JS
12783}
12784
12785static int patch_alc861vd(struct hda_codec *codec)
12786{
12787 struct alc_spec *spec;
12788 int err, board_config;
12789
12790 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12791 if (spec == NULL)
12792 return -ENOMEM;
12793
12794 codec->spec = spec;
12795
12796 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12797 alc861vd_models,
12798 alc861vd_cfg_tbl);
12799
12800 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12801 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12802 "ALC861VD, trying auto-probe from BIOS...\n");
12803 board_config = ALC861VD_AUTO;
12804 }
12805
12806 if (board_config == ALC861VD_AUTO) {
12807 /* automatic parse from the BIOS config */
12808 err = alc861vd_parse_auto_config(codec);
12809 if (err < 0) {
12810 alc_free(codec);
12811 return err;
f12ab1e0 12812 } else if (!err) {
f32610ed
JS
12813 printk(KERN_INFO
12814 "hda_codec: Cannot set up configuration "
12815 "from BIOS. Using base mode...\n");
12816 board_config = ALC861VD_3ST;
12817 }
12818 }
12819
12820 if (board_config != ALC861VD_AUTO)
12821 setup_preset(spec, &alc861vd_presets[board_config]);
12822
12823 spec->stream_name_analog = "ALC861VD Analog";
12824 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12825 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12826
12827 spec->stream_name_digital = "ALC861VD Digital";
12828 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12829 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12830
12831 spec->adc_nids = alc861vd_adc_nids;
12832 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 12833 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed
JS
12834
12835 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12836 spec->num_mixers++;
12837
2134ea4f
TI
12838 spec->vmaster_nid = 0x02;
12839
f32610ed
JS
12840 codec->patch_ops = alc_patch_ops;
12841
12842 if (board_config == ALC861VD_AUTO)
12843 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
12844#ifdef CONFIG_SND_HDA_POWER_SAVE
12845 if (!spec->loopback.amplist)
12846 spec->loopback.amplist = alc861vd_loopbacks;
12847#endif
f32610ed
JS
12848
12849 return 0;
12850}
12851
bc9f98a9
KY
12852/*
12853 * ALC662 support
12854 *
12855 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12856 * configuration. Each pin widget can choose any input DACs and a mixer.
12857 * Each ADC is connected from a mixer of all inputs. This makes possible
12858 * 6-channel independent captures.
12859 *
12860 * In addition, an independent DAC for the multi-playback (not used in this
12861 * driver yet).
12862 */
12863#define ALC662_DIGOUT_NID 0x06
12864#define ALC662_DIGIN_NID 0x0a
12865
12866static hda_nid_t alc662_dac_nids[4] = {
12867 /* front, rear, clfe, rear_surr */
12868 0x02, 0x03, 0x04
12869};
12870
12871static hda_nid_t alc662_adc_nids[1] = {
12872 /* ADC1-2 */
12873 0x09,
12874};
e1406348 12875
77a261b7 12876static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
e1406348 12877
bc9f98a9
KY
12878/* input MUX */
12879/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
12880static struct hda_input_mux alc662_capture_source = {
12881 .num_items = 4,
12882 .items = {
12883 { "Mic", 0x0 },
12884 { "Front Mic", 0x1 },
12885 { "Line", 0x2 },
12886 { "CD", 0x4 },
12887 },
12888};
12889
12890static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12891 .num_items = 2,
12892 .items = {
12893 { "Mic", 0x1 },
12894 { "Line", 0x2 },
12895 },
12896};
291702f0
KY
12897
12898static struct hda_input_mux alc662_eeepc_capture_source = {
12899 .num_items = 2,
12900 .items = {
12901 { "i-Mic", 0x1 },
12902 { "e-Mic", 0x0 },
12903 },
12904};
12905
bc9f98a9
KY
12906#define alc662_mux_enum_info alc_mux_enum_info
12907#define alc662_mux_enum_get alc_mux_enum_get
e1406348 12908#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 12909
bc9f98a9
KY
12910/*
12911 * 2ch mode
12912 */
12913static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12914 { 2, NULL }
12915};
12916
12917/*
12918 * 2ch mode
12919 */
12920static struct hda_verb alc662_3ST_ch2_init[] = {
12921 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12922 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12923 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12924 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12925 { } /* end */
12926};
12927
12928/*
12929 * 6ch mode
12930 */
12931static struct hda_verb alc662_3ST_ch6_init[] = {
12932 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12933 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12934 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12935 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12936 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12937 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12938 { } /* end */
12939};
12940
12941static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12942 { 2, alc662_3ST_ch2_init },
12943 { 6, alc662_3ST_ch6_init },
12944};
12945
12946/*
12947 * 2ch mode
12948 */
12949static struct hda_verb alc662_sixstack_ch6_init[] = {
12950 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12951 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12952 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12953 { } /* end */
12954};
12955
12956/*
12957 * 6ch mode
12958 */
12959static struct hda_verb alc662_sixstack_ch8_init[] = {
12960 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12961 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12962 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12963 { } /* end */
12964};
12965
12966static struct hda_channel_mode alc662_5stack_modes[2] = {
12967 { 2, alc662_sixstack_ch6_init },
12968 { 6, alc662_sixstack_ch8_init },
12969};
12970
12971/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12972 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12973 */
12974
12975static struct snd_kcontrol_new alc662_base_mixer[] = {
12976 /* output mixer control */
12977 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12978 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12979 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12980 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12981 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12982 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12983 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12984 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12986
12987 /*Input mixer control */
12988 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12989 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12990 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12991 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12992 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12993 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12994 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12995 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
12996 { } /* end */
12997};
12998
12999static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
13000 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13001 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13002 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13009 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13010 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13011 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13012 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
13013 { } /* end */
13014};
13015
13016static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
13017 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13018 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13019 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13020 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13021 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13022 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13023 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13024 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13025 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13026 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13027 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13028 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13029 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13030 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13032 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13033 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13034 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13035 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
13036 { } /* end */
13037};
13038
13039static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13040 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13041 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
13042 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13043 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
13044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
13049 { } /* end */
13050};
13051
291702f0 13052static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 13053 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 13054
b4818494
HRK
13055 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13056 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
13057
13058 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13059 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13060 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13061
13062 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13063 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13064 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13065 { } /* end */
13066};
13067
8c427226 13068static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
13069 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13070 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
13071 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13072 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13073 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13074 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13075 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13076 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 13077 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
13078 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13079 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13080 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13083 { } /* end */
13084};
13085
bc9f98a9
KY
13086static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13087 {
13088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13089 .name = "Channel Mode",
13090 .info = alc_ch_mode_info,
13091 .get = alc_ch_mode_get,
13092 .put = alc_ch_mode_put,
13093 },
13094 { } /* end */
13095};
13096
13097static struct hda_verb alc662_init_verbs[] = {
13098 /* ADC: mute amp left and right */
13099 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13100 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13101 /* Front mixer: unmute input/output amp left and right (volume = 0) */
13102
cb53c626
TI
13103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 13108
b60dd394
KY
13109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13110 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13111 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13114 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13115
13116 /* Front Pin: output 0 (0x0c) */
13117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13119
13120 /* Rear Pin: output 1 (0x0d) */
13121 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13123
13124 /* CLFE Pin: output 2 (0x0e) */
13125 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13127
13128 /* Mic (rear) pin: input vref at 80% */
13129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13130 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13131 /* Front Mic pin: input vref at 80% */
13132 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13134 /* Line In pin: input */
13135 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13137 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13138 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13139 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13140 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13141 /* CD pin widget for input */
13142 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13143
13144 /* FIXME: use matrix-type input source selection */
13145 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13146 /* Input mixer */
13147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13149 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13150 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
13151
13152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
bc9f98a9
KY
13156 { }
13157};
13158
13159static struct hda_verb alc662_sue_init_verbs[] = {
13160 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13161 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
13162 {}
13163};
13164
13165static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13166 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13167 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13168 {}
bc9f98a9
KY
13169};
13170
8c427226
KY
13171/* Set Unsolicited Event*/
13172static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13173 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13175 {}
13176};
13177
bc9f98a9
KY
13178/*
13179 * generic initialization of ADC, input mixers and output mixers
13180 */
13181static struct hda_verb alc662_auto_init_verbs[] = {
13182 /*
13183 * Unmute ADC and set the default input to mic-in
13184 */
13185 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13186 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13187
13188 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13189 * mixer widget
13190 * Note: PASD motherboards uses the Line In 2 as the input for front
13191 * panel mic (mic 2)
13192 */
13193 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13194 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13195 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13196 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13197 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13198 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
13199
13200 /*
13201 * Set up output mixers (0x0c - 0x0f)
13202 */
13203 /* set vol=0 to output mixers */
13204 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13205 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13206 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13207
13208 /* set up input amps for analog loopback */
13209 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
13210 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13212 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13213 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13215 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13216
13217
13218 /* FIXME: use matrix-type input source selection */
13219 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13220 /* Input mixer */
13221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 13222 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
13223 { }
13224};
13225
13226/* capture mixer elements */
13227static struct snd_kcontrol_new alc662_capture_mixer[] = {
13228 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13229 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13230 {
13231 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13232 /* The multiple "Capture Source" controls confuse alsamixer
13233 * So call somewhat different..
bc9f98a9
KY
13234 */
13235 /* .name = "Capture Source", */
13236 .name = "Input Source",
13237 .count = 1,
6e7939bb
HRK
13238 .info = alc662_mux_enum_info,
13239 .get = alc662_mux_enum_get,
13240 .put = alc662_mux_enum_put,
bc9f98a9
KY
13241 },
13242 { } /* end */
13243};
13244
13245static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13246{
13247 unsigned int present;
f12ab1e0 13248 unsigned char bits;
bc9f98a9
KY
13249
13250 present = snd_hda_codec_read(codec, 0x14, 0,
13251 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13252 bits = present ? HDA_AMP_MUTE : 0;
13253 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13254 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13255}
13256
13257static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13258{
13259 unsigned int present;
f12ab1e0 13260 unsigned char bits;
bc9f98a9
KY
13261
13262 present = snd_hda_codec_read(codec, 0x1b, 0,
13263 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13264 bits = present ? HDA_AMP_MUTE : 0;
13265 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13266 HDA_AMP_MUTE, bits);
13267 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13268 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13269}
13270
13271static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13272 unsigned int res)
13273{
13274 if ((res >> 26) == ALC880_HP_EVENT)
13275 alc662_lenovo_101e_all_automute(codec);
13276 if ((res >> 26) == ALC880_FRONT_EVENT)
13277 alc662_lenovo_101e_ispeaker_automute(codec);
13278}
13279
291702f0
KY
13280static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13281{
13282 unsigned int present;
13283
13284 present = snd_hda_codec_read(codec, 0x18, 0,
13285 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13286 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13287 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13288 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13289 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13290 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13291 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13292 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13293 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13294}
13295
13296/* unsolicited event for HP jack sensing */
13297static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13298 unsigned int res)
13299{
13300 if ((res >> 26) == ALC880_HP_EVENT)
13301 alc262_hippo1_automute( codec );
13302
13303 if ((res >> 26) == ALC880_MIC_EVENT)
13304 alc662_eeepc_mic_automute(codec);
13305}
13306
13307static void alc662_eeepc_inithook(struct hda_codec *codec)
13308{
13309 alc262_hippo1_automute( codec );
13310 alc662_eeepc_mic_automute(codec);
13311}
13312
8c427226
KY
13313static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13314{
13315 unsigned int mute;
13316 unsigned int present;
13317
13318 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13319 present = snd_hda_codec_read(codec, 0x14, 0,
13320 AC_VERB_GET_PIN_SENSE, 0);
13321 present = (present & 0x80000000) != 0;
13322 if (present) {
13323 /* mute internal speaker */
13324 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13325 HDA_AMP_MUTE, HDA_AMP_MUTE);
13326 } else {
13327 /* unmute internal speaker if necessary */
13328 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13329 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13330 HDA_AMP_MUTE, mute);
13331 }
13332}
13333
13334/* unsolicited event for HP jack sensing */
13335static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13336 unsigned int res)
13337{
13338 if ((res >> 26) == ALC880_HP_EVENT)
13339 alc662_eeepc_ep20_automute(codec);
13340}
13341
13342static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13343{
13344 alc662_eeepc_ep20_automute(codec);
13345}
13346
cb53c626
TI
13347#ifdef CONFIG_SND_HDA_POWER_SAVE
13348#define alc662_loopbacks alc880_loopbacks
13349#endif
13350
bc9f98a9
KY
13351
13352/* pcm configuration: identiacal with ALC880 */
13353#define alc662_pcm_analog_playback alc880_pcm_analog_playback
13354#define alc662_pcm_analog_capture alc880_pcm_analog_capture
13355#define alc662_pcm_digital_playback alc880_pcm_digital_playback
13356#define alc662_pcm_digital_capture alc880_pcm_digital_capture
13357
13358/*
13359 * configuration and preset
13360 */
13361static const char *alc662_models[ALC662_MODEL_LAST] = {
13362 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13363 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13364 [ALC662_3ST_6ch] = "3stack-6ch",
13365 [ALC662_5ST_DIG] = "6stack-dig",
13366 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 13367 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 13368 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
bc9f98a9
KY
13369 [ALC662_AUTO] = "auto",
13370};
13371
13372static struct snd_pci_quirk alc662_cfg_tbl[] = {
291702f0 13373 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 13374 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
ac3e3741 13375 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
bc9f98a9
KY
13376 {}
13377};
13378
13379static struct alc_config_preset alc662_presets[] = {
13380 [ALC662_3ST_2ch_DIG] = {
291702f0 13381 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
13382 .init_verbs = { alc662_init_verbs },
13383 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13384 .dac_nids = alc662_dac_nids,
13385 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13386 .dig_in_nid = ALC662_DIGIN_NID,
13387 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13388 .channel_mode = alc662_3ST_2ch_modes,
13389 .input_mux = &alc662_capture_source,
13390 },
13391 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
13392 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13393 alc662_capture_mixer },
bc9f98a9
KY
13394 .init_verbs = { alc662_init_verbs },
13395 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13396 .dac_nids = alc662_dac_nids,
13397 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13398 .dig_in_nid = ALC662_DIGIN_NID,
13399 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13400 .channel_mode = alc662_3ST_6ch_modes,
13401 .need_dac_fix = 1,
13402 .input_mux = &alc662_capture_source,
f12ab1e0 13403 },
bc9f98a9 13404 [ALC662_3ST_6ch] = {
291702f0
KY
13405 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13406 alc662_capture_mixer },
bc9f98a9
KY
13407 .init_verbs = { alc662_init_verbs },
13408 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13409 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13410 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13411 .channel_mode = alc662_3ST_6ch_modes,
13412 .need_dac_fix = 1,
13413 .input_mux = &alc662_capture_source,
f12ab1e0 13414 },
bc9f98a9 13415 [ALC662_5ST_DIG] = {
291702f0
KY
13416 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13417 alc662_capture_mixer },
bc9f98a9
KY
13418 .init_verbs = { alc662_init_verbs },
13419 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13420 .dac_nids = alc662_dac_nids,
13421 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13422 .dig_in_nid = ALC662_DIGIN_NID,
13423 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13424 .channel_mode = alc662_5stack_modes,
13425 .input_mux = &alc662_capture_source,
13426 },
13427 [ALC662_LENOVO_101E] = {
291702f0 13428 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
13429 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13430 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13431 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13432 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13433 .channel_mode = alc662_3ST_2ch_modes,
13434 .input_mux = &alc662_lenovo_101e_capture_source,
13435 .unsol_event = alc662_lenovo_101e_unsol_event,
13436 .init_hook = alc662_lenovo_101e_all_automute,
13437 },
291702f0
KY
13438 [ALC662_ASUS_EEEPC_P701] = {
13439 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13440 .init_verbs = { alc662_init_verbs,
13441 alc662_eeepc_sue_init_verbs },
13442 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13443 .dac_nids = alc662_dac_nids,
291702f0
KY
13444 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13445 .channel_mode = alc662_3ST_2ch_modes,
13446 .input_mux = &alc662_eeepc_capture_source,
13447 .unsol_event = alc662_eeepc_unsol_event,
13448 .init_hook = alc662_eeepc_inithook,
13449 },
8c427226
KY
13450 [ALC662_ASUS_EEEPC_EP20] = {
13451 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13452 alc662_chmode_mixer },
13453 .init_verbs = { alc662_init_verbs,
13454 alc662_eeepc_ep20_sue_init_verbs },
13455 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13456 .dac_nids = alc662_dac_nids,
8c427226
KY
13457 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13458 .channel_mode = alc662_3ST_6ch_modes,
13459 .input_mux = &alc662_lenovo_101e_capture_source,
13460 .unsol_event = alc662_eeepc_ep20_unsol_event,
13461 .init_hook = alc662_eeepc_ep20_inithook,
13462 },
bc9f98a9
KY
13463
13464};
13465
13466
13467/*
13468 * BIOS auto configuration
13469 */
13470
13471/* add playback controls from the parsed DAC table */
13472static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13473 const struct auto_pin_cfg *cfg)
13474{
13475 char name[32];
13476 static const char *chname[4] = {
13477 "Front", "Surround", NULL /*CLFE*/, "Side"
13478 };
13479 hda_nid_t nid;
13480 int i, err;
13481
13482 for (i = 0; i < cfg->line_outs; i++) {
13483 if (!spec->multiout.dac_nids[i])
13484 continue;
b60dd394 13485 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
13486 if (i == 2) {
13487 /* Center/LFE */
13488 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13489 "Center Playback Volume",
f12ab1e0
TI
13490 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13491 HDA_OUTPUT));
bc9f98a9
KY
13492 if (err < 0)
13493 return err;
13494 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13495 "LFE Playback Volume",
f12ab1e0
TI
13496 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13497 HDA_OUTPUT));
bc9f98a9
KY
13498 if (err < 0)
13499 return err;
13500 err = add_control(spec, ALC_CTL_BIND_MUTE,
13501 "Center Playback Switch",
f12ab1e0
TI
13502 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13503 HDA_INPUT));
bc9f98a9
KY
13504 if (err < 0)
13505 return err;
13506 err = add_control(spec, ALC_CTL_BIND_MUTE,
13507 "LFE Playback Switch",
f12ab1e0
TI
13508 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13509 HDA_INPUT));
bc9f98a9
KY
13510 if (err < 0)
13511 return err;
13512 } else {
13513 sprintf(name, "%s Playback Volume", chname[i]);
13514 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
13515 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13516 HDA_OUTPUT));
bc9f98a9
KY
13517 if (err < 0)
13518 return err;
13519 sprintf(name, "%s Playback Switch", chname[i]);
13520 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
13521 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13522 HDA_INPUT));
bc9f98a9
KY
13523 if (err < 0)
13524 return err;
13525 }
13526 }
13527 return 0;
13528}
13529
13530/* add playback controls for speaker and HP outputs */
13531static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13532 const char *pfx)
13533{
13534 hda_nid_t nid;
13535 int err;
13536 char name[32];
13537
13538 if (!pin)
13539 return 0;
13540
13541 if (alc880_is_fixed_pin(pin)) {
13542 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13543 /* printk("DAC nid=%x\n",nid); */
13544 /* specify the DAC as the extra output */
13545 if (!spec->multiout.hp_nid)
13546 spec->multiout.hp_nid = nid;
13547 else
13548 spec->multiout.extra_out_nid[0] = nid;
13549 /* control HP volume/switch on the output mixer amp */
13550 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13551 sprintf(name, "%s Playback Volume", pfx);
13552 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13553 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13554 if (err < 0)
13555 return err;
13556 sprintf(name, "%s Playback Switch", pfx);
13557 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13558 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13559 if (err < 0)
13560 return err;
13561 } else if (alc880_is_multi_pin(pin)) {
13562 /* set manual connection */
13563 /* we have only a switch on HP-out PIN */
13564 sprintf(name, "%s Playback Switch", pfx);
13565 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13566 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13567 if (err < 0)
13568 return err;
13569 }
13570 return 0;
13571}
13572
13573/* create playback/capture controls for input pins */
13574static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13575 const struct auto_pin_cfg *cfg)
13576{
13577 struct hda_input_mux *imux = &spec->private_imux;
13578 int i, err, idx;
13579
13580 for (i = 0; i < AUTO_PIN_LAST; i++) {
13581 if (alc880_is_input_pin(cfg->input_pins[i])) {
13582 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13583 err = new_analog_input(spec, cfg->input_pins[i],
13584 auto_pin_cfg_labels[i],
13585 idx, 0x0b);
13586 if (err < 0)
13587 return err;
13588 imux->items[imux->num_items].label =
13589 auto_pin_cfg_labels[i];
13590 imux->items[imux->num_items].index =
13591 alc880_input_pin_idx(cfg->input_pins[i]);
13592 imux->num_items++;
13593 }
13594 }
13595 return 0;
13596}
13597
13598static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13599 hda_nid_t nid, int pin_type,
13600 int dac_idx)
13601{
f6c7e546 13602 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
13603 /* need the manual connection? */
13604 if (alc880_is_multi_pin(nid)) {
13605 struct alc_spec *spec = codec->spec;
13606 int idx = alc880_multi_pin_idx(nid);
13607 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13608 AC_VERB_SET_CONNECT_SEL,
13609 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13610 }
13611}
13612
13613static void alc662_auto_init_multi_out(struct hda_codec *codec)
13614{
13615 struct alc_spec *spec = codec->spec;
13616 int i;
13617
8c427226 13618 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
13619 for (i = 0; i <= HDA_SIDE; i++) {
13620 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13621 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 13622 if (nid)
baba8ee9 13623 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
13624 i);
13625 }
13626}
13627
13628static void alc662_auto_init_hp_out(struct hda_codec *codec)
13629{
13630 struct alc_spec *spec = codec->spec;
13631 hda_nid_t pin;
13632
13633 pin = spec->autocfg.hp_pins[0];
13634 if (pin) /* connect to front */
13635 /* use dac 0 */
13636 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
13637 pin = spec->autocfg.speaker_pins[0];
13638 if (pin)
13639 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
13640}
13641
13642#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13643#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13644
13645static void alc662_auto_init_analog_input(struct hda_codec *codec)
13646{
13647 struct alc_spec *spec = codec->spec;
13648 int i;
13649
13650 for (i = 0; i < AUTO_PIN_LAST; i++) {
13651 hda_nid_t nid = spec->autocfg.input_pins[i];
13652 if (alc662_is_input_pin(nid)) {
13653 snd_hda_codec_write(codec, nid, 0,
13654 AC_VERB_SET_PIN_WIDGET_CONTROL,
13655 (i <= AUTO_PIN_FRONT_MIC ?
13656 PIN_VREF80 : PIN_IN));
13657 if (nid != ALC662_PIN_CD_NID)
13658 snd_hda_codec_write(codec, nid, 0,
13659 AC_VERB_SET_AMP_GAIN_MUTE,
13660 AMP_OUT_MUTE);
13661 }
13662 }
13663}
13664
13665static int alc662_parse_auto_config(struct hda_codec *codec)
13666{
13667 struct alc_spec *spec = codec->spec;
13668 int err;
13669 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13670
13671 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13672 alc662_ignore);
13673 if (err < 0)
13674 return err;
13675 if (!spec->autocfg.line_outs)
13676 return 0; /* can't find valid BIOS pin config */
13677
f12ab1e0
TI
13678 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13679 if (err < 0)
13680 return err;
13681 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13682 if (err < 0)
13683 return err;
13684 err = alc662_auto_create_extra_out(spec,
13685 spec->autocfg.speaker_pins[0],
13686 "Speaker");
13687 if (err < 0)
13688 return err;
13689 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13690 "Headphone");
13691 if (err < 0)
13692 return err;
13693 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13694 if (err < 0)
bc9f98a9
KY
13695 return err;
13696
13697 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13698
13699 if (spec->autocfg.dig_out_pin)
13700 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13701
13702 if (spec->kctl_alloc)
13703 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13704
13705 spec->num_mux_defs = 1;
13706 spec->input_mux = &spec->private_imux;
13707
8c87286f 13708 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
13709 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13710 spec->num_mixers++;
8c87286f 13711 return 1;
bc9f98a9
KY
13712}
13713
13714/* additional initialization for auto-configuration model */
13715static void alc662_auto_init(struct hda_codec *codec)
13716{
f6c7e546 13717 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
13718 alc662_auto_init_multi_out(codec);
13719 alc662_auto_init_hp_out(codec);
13720 alc662_auto_init_analog_input(codec);
f6c7e546
TI
13721 if (spec->unsol_event)
13722 alc_sku_automute(codec);
bc9f98a9
KY
13723}
13724
13725static int patch_alc662(struct hda_codec *codec)
13726{
13727 struct alc_spec *spec;
13728 int err, board_config;
13729
13730 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13731 if (!spec)
13732 return -ENOMEM;
13733
13734 codec->spec = spec;
13735
13736 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13737 alc662_models,
13738 alc662_cfg_tbl);
13739 if (board_config < 0) {
13740 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13741 "trying auto-probe from BIOS...\n");
13742 board_config = ALC662_AUTO;
13743 }
13744
13745 if (board_config == ALC662_AUTO) {
13746 /* automatic parse from the BIOS config */
13747 err = alc662_parse_auto_config(codec);
13748 if (err < 0) {
13749 alc_free(codec);
13750 return err;
8c87286f 13751 } else if (!err) {
bc9f98a9
KY
13752 printk(KERN_INFO
13753 "hda_codec: Cannot set up configuration "
13754 "from BIOS. Using base mode...\n");
13755 board_config = ALC662_3ST_2ch_DIG;
13756 }
13757 }
13758
13759 if (board_config != ALC662_AUTO)
13760 setup_preset(spec, &alc662_presets[board_config]);
13761
13762 spec->stream_name_analog = "ALC662 Analog";
13763 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13764 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13765
13766 spec->stream_name_digital = "ALC662 Digital";
13767 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13768 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13769
e1406348
TI
13770 spec->adc_nids = alc662_adc_nids;
13771 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13772 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 13773
2134ea4f
TI
13774 spec->vmaster_nid = 0x02;
13775
bc9f98a9
KY
13776 codec->patch_ops = alc_patch_ops;
13777 if (board_config == ALC662_AUTO)
13778 spec->init_hook = alc662_auto_init;
cb53c626
TI
13779#ifdef CONFIG_SND_HDA_POWER_SAVE
13780 if (!spec->loopback.amplist)
13781 spec->loopback.amplist = alc662_loopbacks;
13782#endif
bc9f98a9
KY
13783
13784 return 0;
13785}
13786
1da177e4
LT
13787/*
13788 * patch entries
13789 */
13790struct hda_codec_preset snd_hda_preset_realtek[] = {
13791 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 13792 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 13793 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 13794 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 13795 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 13796 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 13797 .patch = patch_alc861 },
f32610ed
JS
13798 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13799 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13800 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
13801 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13802 .patch = patch_alc883 },
13803 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13804 .patch = patch_alc662 },
f32610ed 13805 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 13806 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 13807 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
df694daa 13808 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 13809 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 13810 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
13811 {} /* terminator */
13812};