Merge branch 'fix/hda' into topic/hda
[GitHub/mt8127/android_kernel_alcatel_ttab.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"
680cd536 33#include "hda_beep.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,
df99cd33 63 ALC880_MEDION_RIM,
e9edcee0
TI
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
df694daa 67 ALC880_AUTO,
16ded525
TI
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
3f878308 75 ALC260_HP_DC7600,
df694daa
KY
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
0bfc90e9 78 ALC260_ACER,
bc9f98a9
KY
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
cc959489 81 ALC260_FAVORIT100,
7cf51e48
JW
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
df694daa 85 ALC260_AUTO,
16ded525 86 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
87};
88
df694daa
KY
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
ccc656ce
KY
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
834be88d 94 ALC262_FUJITSU,
9c7f852e 95 ALC262_HP_BPC,
cd7509a4
KY
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
66d2a9d6 98 ALC262_HP_TC_T5735,
8c427226 99 ALC262_HP_RP5700,
304dcaac 100 ALC262_BENQ_ED8,
272a527c 101 ALC262_SONY_ASSAMD,
83c34218 102 ALC262_BENQ_T31,
f651b50b 103 ALC262_ULTRA,
0e31daf7 104 ALC262_LENOVO_3000,
e8f9ae2a 105 ALC262_NEC,
4e555fe5 106 ALC262_TOSHIBA_S06,
9f99a638 107 ALC262_TOSHIBA_RX1,
ba340e82 108 ALC262_TYAN,
df694daa
KY
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
a361d84b
KY
113/* ALC268 models */
114enum {
eb5a6621 115 ALC267_QUANTA_IL1,
a361d84b 116 ALC268_3ST,
d1a991a6 117 ALC268_TOSHIBA,
d273809e 118 ALC268_ACER,
c238b4f4 119 ALC268_ACER_DMIC,
8ef355da 120 ALC268_ACER_ASPIRE_ONE,
3866f0b0 121 ALC268_DELL,
f12462c5 122 ALC268_ZEPTO,
86c53bd2
JW
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
a361d84b
KY
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
f6a92248
KY
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
60db6b53 133 ALC269_QUANTA_FL1,
f53281e6
KY
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
26f5df26 136 ALC269_FUJITSU,
64154835 137 ALC269_LIFEBOOK,
f6a92248
KY
138 ALC269_AUTO,
139 ALC269_MODEL_LAST /* last tag */
140};
141
df694daa
KY
142/* ALC861 models */
143enum {
144 ALC861_3ST,
9c7f852e 145 ALC660_3ST,
df694daa
KY
146 ALC861_3ST_DIG,
147 ALC861_6ST_DIG,
22309c3e 148 ALC861_UNIWILL_M31,
a53d1aec 149 ALC861_TOSHIBA,
7cdbff94 150 ALC861_ASUS,
56bb0cab 151 ALC861_ASUS_LAPTOP,
df694daa
KY
152 ALC861_AUTO,
153 ALC861_MODEL_LAST,
154};
155
f32610ed
JS
156/* ALC861-VD models */
157enum {
158 ALC660VD_3ST,
6963f84c 159 ALC660VD_3ST_DIG,
13c94744 160 ALC660VD_ASUS_V1S,
f32610ed
JS
161 ALC861VD_3ST,
162 ALC861VD_3ST_DIG,
163 ALC861VD_6ST_DIG,
bdd148a3 164 ALC861VD_LENOVO,
272a527c 165 ALC861VD_DALLAS,
d1a991a6 166 ALC861VD_HP,
f32610ed
JS
167 ALC861VD_AUTO,
168 ALC861VD_MODEL_LAST,
169};
170
bc9f98a9
KY
171/* ALC662 models */
172enum {
173 ALC662_3ST_2ch_DIG,
174 ALC662_3ST_6ch_DIG,
175 ALC662_3ST_6ch,
176 ALC662_5ST_DIG,
177 ALC662_LENOVO_101E,
291702f0 178 ALC662_ASUS_EEEPC_P701,
8c427226 179 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
180 ALC663_ASUS_M51VA,
181 ALC663_ASUS_G71V,
182 ALC663_ASUS_H13,
183 ALC663_ASUS_G50V,
f1d4e28b
KY
184 ALC662_ECS,
185 ALC663_ASUS_MODE1,
186 ALC662_ASUS_MODE2,
187 ALC663_ASUS_MODE3,
188 ALC663_ASUS_MODE4,
189 ALC663_ASUS_MODE5,
190 ALC663_ASUS_MODE6,
622e84cd
KY
191 ALC272_DELL,
192 ALC272_DELL_ZM1,
bc9f98a9
KY
193 ALC662_AUTO,
194 ALC662_MODEL_LAST,
195};
196
df694daa
KY
197/* ALC882 models */
198enum {
199 ALC882_3ST_DIG,
200 ALC882_6ST_DIG,
4b146cb0 201 ALC882_ARIMA,
bdd148a3 202 ALC882_W2JC,
272a527c
KY
203 ALC882_TARGA,
204 ALC882_ASUS_A7J,
914759b7 205 ALC882_ASUS_A7M,
9102cd1c 206 ALC885_MACPRO,
87350ad0 207 ALC885_MBP3,
c54728d8 208 ALC885_IMAC24,
272a527c 209 ALC882_AUTO,
df694daa
KY
210 ALC882_MODEL_LAST,
211};
212
9c7f852e
TI
213/* ALC883 models */
214enum {
215 ALC883_3ST_2ch_DIG,
216 ALC883_3ST_6ch_DIG,
217 ALC883_3ST_6ch,
218 ALC883_6ST_DIG,
ccc656ce
KY
219 ALC883_TARGA_DIG,
220 ALC883_TARGA_2ch_DIG,
bab282b9 221 ALC883_ACER,
2880a867 222 ALC883_ACER_ASPIRE,
5b2d1eca 223 ALC888_ACER_ASPIRE_4930G,
c07584c8 224 ALC883_MEDION,
ea1fb29a 225 ALC883_MEDION_MD2,
b373bdeb 226 ALC883_LAPTOP_EAPD,
bc9f98a9 227 ALC883_LENOVO_101E_2ch,
272a527c 228 ALC883_LENOVO_NB0763,
189609ae 229 ALC888_LENOVO_MS7195_DIG,
e2757d5e 230 ALC888_LENOVO_SKY,
ea1fb29a 231 ALC883_HAIER_W66,
4723c022 232 ALC888_3ST_HP,
5795b9e6 233 ALC888_6ST_DELL,
a8848bd6 234 ALC883_MITAC,
0c4cc443 235 ALC883_CLEVO_M720,
fb97dc67 236 ALC883_FUJITSU_PI2515,
ef8ef5fb 237 ALC888_FUJITSU_XA3530,
17bba1b7 238 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
239 ALC888_ASUS_M90V,
240 ALC888_ASUS_EEE1601,
3ab90935 241 ALC1200_ASUS_P5Q,
9c7f852e
TI
242 ALC883_AUTO,
243 ALC883_MODEL_LAST,
244};
245
61b9b9b1
HRK
246/* styles of capture selection */
247enum {
248 CAPT_MUX = 0, /* only mux based */
249 CAPT_MIX, /* only mixer based */
250 CAPT_1MUX_MIX, /* first mux and other mixers */
251};
252
df694daa
KY
253/* for GPIO Poll */
254#define GPIO_MASK 0x03
255
1da177e4
LT
256struct alc_spec {
257 /* codec parameterization */
df694daa 258 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 259 unsigned int num_mixers;
f9e336f6 260 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 261 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 262
df694daa 263 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
264 * don't forget NULL
265 * termination!
e9edcee0
TI
266 */
267 unsigned int num_init_verbs;
1da177e4 268
16ded525 269 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
270 struct hda_pcm_stream *stream_analog_playback;
271 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
272 struct hda_pcm_stream *stream_analog_alt_playback;
273 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 274
f12ab1e0 275 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
276 struct hda_pcm_stream *stream_digital_playback;
277 struct hda_pcm_stream *stream_digital_capture;
278
279 /* playback */
16ded525
TI
280 struct hda_multi_out multiout; /* playback set-up
281 * max_channels, dacs must be set
282 * dig_out_nid and hp_nid are optional
283 */
6330079f 284 hda_nid_t alt_dac_nid;
6a05ac4a 285 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 286 int dig_out_type;
1da177e4
LT
287
288 /* capture */
289 unsigned int num_adc_nids;
290 hda_nid_t *adc_nids;
e1406348 291 hda_nid_t *capsrc_nids;
16ded525 292 hda_nid_t dig_in_nid; /* digital-in NID; optional */
61b9b9b1 293 int capture_style; /* capture style (CAPT_*) */
1da177e4
LT
294
295 /* capture source */
a1e8d2da 296 unsigned int num_mux_defs;
1da177e4
LT
297 const struct hda_input_mux *input_mux;
298 unsigned int cur_mux[3];
299
300 /* channel model */
d2a6d7dc 301 const struct hda_channel_mode *channel_mode;
1da177e4 302 int num_channel_mode;
4e195a7b 303 int need_dac_fix;
1da177e4
LT
304
305 /* PCM information */
4c5186ed 306 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 307
e9edcee0
TI
308 /* dynamic controls, init_verbs and input_mux */
309 struct auto_pin_cfg autocfg;
603c4019 310 struct snd_array kctls;
61b9b9b1 311 struct hda_input_mux private_imux[3];
41923e44 312 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 313
ae6b813a
TI
314 /* hooks */
315 void (*init_hook)(struct hda_codec *codec);
316 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
317
834be88d
TI
318 /* for pin sensing */
319 unsigned int sense_updated: 1;
320 unsigned int jack_present: 1;
bec15c3a 321 unsigned int master_sw: 1;
cb53c626 322
e64f14f4
TI
323 /* other flags */
324 unsigned int no_analog :1; /* digital I/O only */
325
2134ea4f
TI
326 /* for virtual master */
327 hda_nid_t vmaster_nid;
cb53c626
TI
328#ifdef CONFIG_SND_HDA_POWER_SAVE
329 struct hda_loopback_check loopback;
330#endif
2c3bf9ab
TI
331
332 /* for PLL fix */
333 hda_nid_t pll_nid;
334 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
335};
336
337/*
338 * configuration template - to be copied to the spec instance
339 */
340struct alc_config_preset {
9c7f852e
TI
341 struct snd_kcontrol_new *mixers[5]; /* should be identical size
342 * with spec
343 */
f9e336f6 344 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
345 const struct hda_verb *init_verbs[5];
346 unsigned int num_dacs;
347 hda_nid_t *dac_nids;
348 hda_nid_t dig_out_nid; /* optional */
349 hda_nid_t hp_nid; /* optional */
b25c9da1 350 hda_nid_t *slave_dig_outs;
df694daa
KY
351 unsigned int num_adc_nids;
352 hda_nid_t *adc_nids;
e1406348 353 hda_nid_t *capsrc_nids;
df694daa
KY
354 hda_nid_t dig_in_nid;
355 unsigned int num_channel_mode;
356 const struct hda_channel_mode *channel_mode;
4e195a7b 357 int need_dac_fix;
a1e8d2da 358 unsigned int num_mux_defs;
df694daa 359 const struct hda_input_mux *input_mux;
ae6b813a
TI
360 void (*unsol_event)(struct hda_codec *, unsigned int);
361 void (*init_hook)(struct hda_codec *);
cb53c626
TI
362#ifdef CONFIG_SND_HDA_POWER_SAVE
363 struct hda_amp_list *loopbacks;
364#endif
1da177e4
LT
365};
366
1da177e4
LT
367
368/*
369 * input MUX handling
370 */
9c7f852e
TI
371static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
372 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
373{
374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
375 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
376 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
377 if (mux_idx >= spec->num_mux_defs)
378 mux_idx = 0;
379 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
380}
381
9c7f852e
TI
382static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
384{
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
388
389 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
390 return 0;
391}
392
9c7f852e
TI
393static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
395{
396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct alc_spec *spec = codec->spec;
cd896c33 398 const struct hda_input_mux *imux;
1da177e4 399 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 400 unsigned int mux_idx;
e1406348
TI
401 hda_nid_t nid = spec->capsrc_nids ?
402 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4 403
cd896c33
TI
404 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
405 imux = &spec->input_mux[mux_idx];
406
61b9b9b1
HRK
407 if (spec->capture_style &&
408 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
54cbc9ab
TI
409 /* Matrix-mixer style (e.g. ALC882) */
410 unsigned int *cur_val = &spec->cur_mux[adc_idx];
411 unsigned int i, idx;
412
413 idx = ucontrol->value.enumerated.item[0];
414 if (idx >= imux->num_items)
415 idx = imux->num_items - 1;
416 if (*cur_val == idx)
417 return 0;
418 for (i = 0; i < imux->num_items; i++) {
419 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
420 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
421 imux->items[i].index,
422 HDA_AMP_MUTE, v);
423 }
424 *cur_val = idx;
425 return 1;
426 } else {
427 /* MUX style (e.g. ALC880) */
cd896c33 428 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
429 &spec->cur_mux[adc_idx]);
430 }
431}
e9edcee0 432
1da177e4
LT
433/*
434 * channel mode setting
435 */
9c7f852e
TI
436static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
438{
439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
440 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
441 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
442 spec->num_channel_mode);
1da177e4
LT
443}
444
9c7f852e
TI
445static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
447{
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct alc_spec *spec = codec->spec;
d2a6d7dc 450 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
451 spec->num_channel_mode,
452 spec->multiout.max_channels);
1da177e4
LT
453}
454
9c7f852e
TI
455static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
457{
458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
459 struct alc_spec *spec = codec->spec;
4e195a7b
TI
460 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
461 spec->num_channel_mode,
462 &spec->multiout.max_channels);
bd2033f2 463 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
464 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
465 return err;
1da177e4
LT
466}
467
a9430dd8 468/*
4c5186ed 469 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 470 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
471 * being part of a format specifier. Maximum allowed length of a value is
472 * 63 characters plus NULL terminator.
7cf51e48
JW
473 *
474 * Note: some retasking pin complexes seem to ignore requests for input
475 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
476 * are requested. Therefore order this list so that this behaviour will not
477 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
478 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
479 * March 2006.
4c5186ed
JW
480 */
481static char *alc_pin_mode_names[] = {
7cf51e48
JW
482 "Mic 50pc bias", "Mic 80pc bias",
483 "Line in", "Line out", "Headphone out",
4c5186ed
JW
484};
485static unsigned char alc_pin_mode_values[] = {
7cf51e48 486 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
487};
488/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
489 * in the pin being assumed to be exclusively an input or an output pin. In
490 * addition, "input" pins may or may not process the mic bias option
491 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
492 * accept requests for bias as of chip versions up to March 2006) and/or
493 * wiring in the computer.
a9430dd8 494 */
a1e8d2da
JW
495#define ALC_PIN_DIR_IN 0x00
496#define ALC_PIN_DIR_OUT 0x01
497#define ALC_PIN_DIR_INOUT 0x02
498#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
499#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 500
ea1fb29a 501/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
502 * For each direction the minimum and maximum values are given.
503 */
a1e8d2da 504static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
505 { 0, 2 }, /* ALC_PIN_DIR_IN */
506 { 3, 4 }, /* ALC_PIN_DIR_OUT */
507 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
508 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
509 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
510};
511#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
512#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
513#define alc_pin_mode_n_items(_dir) \
514 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
515
9c7f852e
TI
516static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
a9430dd8 518{
4c5186ed
JW
519 unsigned int item_num = uinfo->value.enumerated.item;
520 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
521
522 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 523 uinfo->count = 1;
4c5186ed
JW
524 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
525
526 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
527 item_num = alc_pin_mode_min(dir);
528 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
529 return 0;
530}
531
9c7f852e
TI
532static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
a9430dd8 534{
4c5186ed 535 unsigned int i;
a9430dd8
JW
536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 538 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 539 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
540 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
541 AC_VERB_GET_PIN_WIDGET_CONTROL,
542 0x00);
a9430dd8 543
4c5186ed
JW
544 /* Find enumerated value for current pinctl setting */
545 i = alc_pin_mode_min(dir);
9c7f852e 546 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 547 i++;
9c7f852e 548 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
549 return 0;
550}
551
9c7f852e
TI
552static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
a9430dd8 554{
4c5186ed 555 signed int change;
a9430dd8
JW
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
558 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
559 long val = *ucontrol->value.integer.value;
9c7f852e
TI
560 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
561 AC_VERB_GET_PIN_WIDGET_CONTROL,
562 0x00);
a9430dd8 563
f12ab1e0 564 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
565 val = alc_pin_mode_min(dir);
566
567 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
568 if (change) {
569 /* Set pin mode to that requested */
82beb8fd
TI
570 snd_hda_codec_write_cache(codec, nid, 0,
571 AC_VERB_SET_PIN_WIDGET_CONTROL,
572 alc_pin_mode_values[val]);
cdcd9268 573
ea1fb29a 574 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
575 * for the requested pin mode. Enum values of 2 or less are
576 * input modes.
577 *
578 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
579 * reduces noise slightly (particularly on input) so we'll
580 * do it. However, having both input and output buffers
581 * enabled simultaneously doesn't seem to be problematic if
582 * this turns out to be necessary in the future.
cdcd9268
JW
583 */
584 if (val <= 2) {
47fd830a
TI
585 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
586 HDA_AMP_MUTE, HDA_AMP_MUTE);
587 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
588 HDA_AMP_MUTE, 0);
cdcd9268 589 } else {
47fd830a
TI
590 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
591 HDA_AMP_MUTE, HDA_AMP_MUTE);
592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
593 HDA_AMP_MUTE, 0);
cdcd9268
JW
594 }
595 }
a9430dd8
JW
596 return change;
597}
598
4c5186ed 599#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 600 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
601 .info = alc_pin_mode_info, \
602 .get = alc_pin_mode_get, \
603 .put = alc_pin_mode_put, \
604 .private_value = nid | (dir<<16) }
df694daa 605
5c8f858d
JW
606/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
607 * together using a mask with more than one bit set. This control is
608 * currently used only by the ALC260 test model. At this stage they are not
609 * needed for any "production" models.
610 */
611#ifdef CONFIG_SND_DEBUG
a5ce8890 612#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 613
9c7f852e
TI
614static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
616{
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
621 unsigned int val = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
623
624 *valp = (val & mask) != 0;
625 return 0;
626}
9c7f852e
TI
627static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
629{
630 signed int change;
631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632 hda_nid_t nid = kcontrol->private_value & 0xffff;
633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634 long val = *ucontrol->value.integer.value;
9c7f852e
TI
635 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
636 AC_VERB_GET_GPIO_DATA,
637 0x00);
5c8f858d
JW
638
639 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
640 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
641 if (val == 0)
5c8f858d
JW
642 gpio_data &= ~mask;
643 else
644 gpio_data |= mask;
82beb8fd
TI
645 snd_hda_codec_write_cache(codec, nid, 0,
646 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
647
648 return change;
649}
650#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
652 .info = alc_gpio_data_info, \
653 .get = alc_gpio_data_get, \
654 .put = alc_gpio_data_put, \
655 .private_value = nid | (mask<<16) }
656#endif /* CONFIG_SND_DEBUG */
657
92621f13
JW
658/* A switch control to allow the enabling of the digital IO pins on the
659 * ALC260. This is incredibly simplistic; the intention of this control is
660 * to provide something in the test model allowing digital outputs to be
661 * identified if present. If models are found which can utilise these
662 * outputs a more complete mixer control can be devised for those models if
663 * necessary.
664 */
665#ifdef CONFIG_SND_DEBUG
a5ce8890 666#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 667
9c7f852e
TI
668static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
670{
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672 hda_nid_t nid = kcontrol->private_value & 0xffff;
673 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
674 long *valp = ucontrol->value.integer.value;
9c7f852e 675 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 676 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
677
678 *valp = (val & mask) != 0;
679 return 0;
680}
9c7f852e
TI
681static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
682 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
683{
684 signed int change;
685 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
686 hda_nid_t nid = kcontrol->private_value & 0xffff;
687 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
688 long val = *ucontrol->value.integer.value;
9c7f852e 689 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 690 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 691 0x00);
92621f13
JW
692
693 /* Set/unset the masked control bit(s) as needed */
9c7f852e 694 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
695 if (val==0)
696 ctrl_data &= ~mask;
697 else
698 ctrl_data |= mask;
82beb8fd
TI
699 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
700 ctrl_data);
92621f13
JW
701
702 return change;
703}
704#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
705 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
706 .info = alc_spdif_ctrl_info, \
707 .get = alc_spdif_ctrl_get, \
708 .put = alc_spdif_ctrl_put, \
709 .private_value = nid | (mask<<16) }
710#endif /* CONFIG_SND_DEBUG */
711
f8225f6d
JW
712/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
713 * Again, this is only used in the ALC26x test models to help identify when
714 * the EAPD line must be asserted for features to work.
715 */
716#ifdef CONFIG_SND_DEBUG
717#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
718
719static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
720 struct snd_ctl_elem_value *ucontrol)
721{
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 hda_nid_t nid = kcontrol->private_value & 0xffff;
724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725 long *valp = ucontrol->value.integer.value;
726 unsigned int val = snd_hda_codec_read(codec, nid, 0,
727 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
728
729 *valp = (val & mask) != 0;
730 return 0;
731}
732
733static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *ucontrol)
735{
736 int change;
737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
738 hda_nid_t nid = kcontrol->private_value & 0xffff;
739 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
740 long val = *ucontrol->value.integer.value;
741 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
742 AC_VERB_GET_EAPD_BTLENABLE,
743 0x00);
744
745 /* Set/unset the masked control bit(s) as needed */
746 change = (!val ? 0 : mask) != (ctrl_data & mask);
747 if (!val)
748 ctrl_data &= ~mask;
749 else
750 ctrl_data |= mask;
751 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
752 ctrl_data);
753
754 return change;
755}
756
757#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
758 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
759 .info = alc_eapd_ctrl_info, \
760 .get = alc_eapd_ctrl_get, \
761 .put = alc_eapd_ctrl_put, \
762 .private_value = nid | (mask<<16) }
763#endif /* CONFIG_SND_DEBUG */
764
23f0c048
TI
765/*
766 * set up the input pin config (depending on the given auto-pin type)
767 */
768static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
769 int auto_pin_type)
770{
771 unsigned int val = PIN_IN;
772
773 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
774 unsigned int pincap;
1327a32b 775 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
776 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
777 if (pincap & AC_PINCAP_VREF_80)
778 val = PIN_VREF80;
779 }
780 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
781}
782
d88897ea
TI
783/*
784 */
785static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
786{
787 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
788 return;
789 spec->mixers[spec->num_mixers++] = mix;
790}
791
792static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
793{
794 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
795 return;
796 spec->init_verbs[spec->num_init_verbs++] = verb;
797}
798
daead538
TI
799#ifdef CONFIG_PROC_FS
800/*
801 * hook for proc
802 */
803static void print_realtek_coef(struct snd_info_buffer *buffer,
804 struct hda_codec *codec, hda_nid_t nid)
805{
806 int coeff;
807
808 if (nid != 0x20)
809 return;
810 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
811 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
812 coeff = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_COEF_INDEX, 0);
814 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
815}
816#else
817#define print_realtek_coef NULL
818#endif
819
df694daa
KY
820/*
821 * set up from the preset table
822 */
9c7f852e
TI
823static void setup_preset(struct alc_spec *spec,
824 const struct alc_config_preset *preset)
df694daa
KY
825{
826 int i;
827
828 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 829 add_mixer(spec, preset->mixers[i]);
f9e336f6 830 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
831 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
832 i++)
d88897ea 833 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 834
df694daa
KY
835 spec->channel_mode = preset->channel_mode;
836 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 837 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
838
839 spec->multiout.max_channels = spec->channel_mode[0].channels;
840
841 spec->multiout.num_dacs = preset->num_dacs;
842 spec->multiout.dac_nids = preset->dac_nids;
843 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 844 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 845 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 846
a1e8d2da 847 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 848 if (!spec->num_mux_defs)
a1e8d2da 849 spec->num_mux_defs = 1;
df694daa
KY
850 spec->input_mux = preset->input_mux;
851
852 spec->num_adc_nids = preset->num_adc_nids;
853 spec->adc_nids = preset->adc_nids;
e1406348 854 spec->capsrc_nids = preset->capsrc_nids;
df694daa 855 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
856
857 spec->unsol_event = preset->unsol_event;
858 spec->init_hook = preset->init_hook;
cb53c626
TI
859#ifdef CONFIG_SND_HDA_POWER_SAVE
860 spec->loopback.amplist = preset->loopbacks;
861#endif
df694daa
KY
862}
863
bc9f98a9
KY
864/* Enable GPIO mask and set output */
865static struct hda_verb alc_gpio1_init_verbs[] = {
866 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
867 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
868 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
869 { }
870};
871
872static struct hda_verb alc_gpio2_init_verbs[] = {
873 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
874 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
875 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
876 { }
877};
878
bdd148a3
KY
879static struct hda_verb alc_gpio3_init_verbs[] = {
880 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
881 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
882 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
883 { }
884};
885
2c3bf9ab
TI
886/*
887 * Fix hardware PLL issue
888 * On some codecs, the analog PLL gating control must be off while
889 * the default value is 1.
890 */
891static void alc_fix_pll(struct hda_codec *codec)
892{
893 struct alc_spec *spec = codec->spec;
894 unsigned int val;
895
896 if (!spec->pll_nid)
897 return;
898 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
899 spec->pll_coef_idx);
900 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
901 AC_VERB_GET_PROC_COEF, 0);
902 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
903 spec->pll_coef_idx);
904 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
905 val & ~(1 << spec->pll_coef_bit));
906}
907
908static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
909 unsigned int coef_idx, unsigned int coef_bit)
910{
911 struct alc_spec *spec = codec->spec;
912 spec->pll_nid = nid;
913 spec->pll_coef_idx = coef_idx;
914 spec->pll_coef_bit = coef_bit;
915 alc_fix_pll(codec);
916}
917
c9b58006
KY
918static void alc_sku_automute(struct hda_codec *codec)
919{
920 struct alc_spec *spec = codec->spec;
c9b58006
KY
921 unsigned int present;
922 unsigned int hp_nid = spec->autocfg.hp_pins[0];
923 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
924
925 /* need to execute and sync at first */
926 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
927 present = snd_hda_codec_read(codec, hp_nid, 0,
928 AC_VERB_GET_PIN_SENSE, 0);
929 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
930 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
931 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
932}
933
4605b718 934#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
935static void alc_mic_automute(struct hda_codec *codec)
936{
937 struct alc_spec *spec = codec->spec;
938 unsigned int present;
939 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
940 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
941 unsigned int mix_nid = spec->capsrc_nids[0];
942 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
943
944 capsrc_idx_mic = mic_nid - 0x18;
945 capsrc_idx_fmic = fmic_nid - 0x18;
946 present = snd_hda_codec_read(codec, mic_nid, 0,
947 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
948 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
949 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
950 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
951 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
952 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
953 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
954}
4605b718 955#else
45bdd1c1 956#define alc_mic_automute(codec) do {} while(0) /* NOP */
4605b718 957#endif /* disabled */
7fb0d78f 958
c9b58006
KY
959/* unsolicited event for HP jack sensing */
960static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
961{
962 if (codec->vendor_id == 0x10ec0880)
963 res >>= 28;
964 else
965 res >>= 26;
7fb0d78f
KY
966 if (res == ALC880_HP_EVENT)
967 alc_sku_automute(codec);
c9b58006 968
7fb0d78f
KY
969 if (res == ALC880_MIC_EVENT)
970 alc_mic_automute(codec);
971}
972
973static void alc_inithook(struct hda_codec *codec)
974{
c9b58006 975 alc_sku_automute(codec);
7fb0d78f 976 alc_mic_automute(codec);
c9b58006
KY
977}
978
f9423e7a
KY
979/* additional initialization for ALC888 variants */
980static void alc888_coef_init(struct hda_codec *codec)
981{
982 unsigned int tmp;
983
984 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
985 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
986 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 987 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
988 /* alc888S-VC */
989 snd_hda_codec_read(codec, 0x20, 0,
990 AC_VERB_SET_PROC_COEF, 0x830);
991 else
992 /* alc888-VB */
993 snd_hda_codec_read(codec, 0x20, 0,
994 AC_VERB_SET_PROC_COEF, 0x3030);
995}
996
bc9f98a9
KY
997/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
998 * 31 ~ 16 : Manufacture ID
999 * 15 ~ 8 : SKU ID
1000 * 7 ~ 0 : Assembly ID
1001 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1002 */
1003static void alc_subsystem_id(struct hda_codec *codec,
1004 unsigned int porta, unsigned int porte,
1005 unsigned int portd)
1006{
c9b58006
KY
1007 unsigned int ass, tmp, i;
1008 unsigned nid;
1009 struct alc_spec *spec = codec->spec;
bc9f98a9 1010
c9b58006
KY
1011 ass = codec->subsystem_id & 0xffff;
1012 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1013 goto do_sku;
1014
ea1fb29a 1015 /*
c9b58006
KY
1016 * 31~30 : port conetcivity
1017 * 29~21 : reserve
1018 * 20 : PCBEEP input
1019 * 19~16 : Check sum (15:1)
1020 * 15~1 : Custom
1021 * 0 : override
1022 */
1023 nid = 0x1d;
1024 if (codec->vendor_id == 0x10ec0260)
1025 nid = 0x17;
0e8a21b5 1026 ass = snd_hda_codec_get_pincfg(codec, nid);
586be3fc
TI
1027 snd_printd("realtek: No valid SSID, "
1028 "checking pincfg 0x%08x for NID 0x%x\n",
dfed0ef9 1029 ass, nid);
c9b58006
KY
1030 if (!(ass & 1) && !(ass & 0x100000))
1031 return;
1032 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
1033 return;
1034
c9b58006
KY
1035 /* check sum */
1036 tmp = 0;
1037 for (i = 1; i < 16; i++) {
8c427226 1038 if ((ass >> i) & 1)
c9b58006
KY
1039 tmp++;
1040 }
1041 if (((ass >> 16) & 0xf) != tmp)
1042 return;
1043do_sku:
586be3fc
TI
1044 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1045 ass & 0xffff, codec->vendor_id);
c9b58006
KY
1046 /*
1047 * 0 : override
1048 * 1 : Swap Jack
1049 * 2 : 0 --> Desktop, 1 --> Laptop
1050 * 3~5 : External Amplifier control
1051 * 7~6 : Reserved
1052 */
bc9f98a9
KY
1053 tmp = (ass & 0x38) >> 3; /* external Amp control */
1054 switch (tmp) {
1055 case 1:
1056 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1057 break;
1058 case 3:
1059 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1060 break;
bdd148a3
KY
1061 case 7:
1062 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1063 break;
c9b58006 1064 case 5: /* set EAPD output high */
bdd148a3 1065 switch (codec->vendor_id) {
c9b58006
KY
1066 case 0x10ec0260:
1067 snd_hda_codec_write(codec, 0x0f, 0,
1068 AC_VERB_SET_EAPD_BTLENABLE, 2);
1069 snd_hda_codec_write(codec, 0x10, 0,
1070 AC_VERB_SET_EAPD_BTLENABLE, 2);
1071 break;
1072 case 0x10ec0262:
bdd148a3
KY
1073 case 0x10ec0267:
1074 case 0x10ec0268:
c9b58006 1075 case 0x10ec0269:
c6e8f2da 1076 case 0x10ec0272:
f9423e7a
KY
1077 case 0x10ec0660:
1078 case 0x10ec0662:
1079 case 0x10ec0663:
c9b58006 1080 case 0x10ec0862:
20a3a05d 1081 case 0x10ec0889:
bdd148a3
KY
1082 snd_hda_codec_write(codec, 0x14, 0,
1083 AC_VERB_SET_EAPD_BTLENABLE, 2);
1084 snd_hda_codec_write(codec, 0x15, 0,
1085 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 1086 break;
bdd148a3 1087 }
c9b58006
KY
1088 switch (codec->vendor_id) {
1089 case 0x10ec0260:
1090 snd_hda_codec_write(codec, 0x1a, 0,
1091 AC_VERB_SET_COEF_INDEX, 7);
1092 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1093 AC_VERB_GET_PROC_COEF, 0);
1094 snd_hda_codec_write(codec, 0x1a, 0,
1095 AC_VERB_SET_COEF_INDEX, 7);
1096 snd_hda_codec_write(codec, 0x1a, 0,
1097 AC_VERB_SET_PROC_COEF,
1098 tmp | 0x2010);
1099 break;
1100 case 0x10ec0262:
1101 case 0x10ec0880:
1102 case 0x10ec0882:
1103 case 0x10ec0883:
1104 case 0x10ec0885:
4a5a4c56 1105 case 0x10ec0887:
20a3a05d 1106 case 0x10ec0889:
c9b58006
KY
1107 snd_hda_codec_write(codec, 0x20, 0,
1108 AC_VERB_SET_COEF_INDEX, 7);
1109 tmp = snd_hda_codec_read(codec, 0x20, 0,
1110 AC_VERB_GET_PROC_COEF, 0);
1111 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1112 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1113 snd_hda_codec_write(codec, 0x20, 0,
1114 AC_VERB_SET_PROC_COEF,
1115 tmp | 0x2010);
1116 break;
f9423e7a 1117 case 0x10ec0888:
1082c748 1118 /*alc888_coef_init(codec);*/ /* called in alc_init() */
f9423e7a 1119 break;
c9b58006
KY
1120 case 0x10ec0267:
1121 case 0x10ec0268:
1122 snd_hda_codec_write(codec, 0x20, 0,
1123 AC_VERB_SET_COEF_INDEX, 7);
1124 tmp = snd_hda_codec_read(codec, 0x20, 0,
1125 AC_VERB_GET_PROC_COEF, 0);
1126 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1127 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1128 snd_hda_codec_write(codec, 0x20, 0,
1129 AC_VERB_SET_PROC_COEF,
1130 tmp | 0x3000);
1131 break;
bc9f98a9 1132 }
c9b58006 1133 default:
bc9f98a9
KY
1134 break;
1135 }
ea1fb29a 1136
8c427226 1137 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1138 * when the external headphone out jack is plugged"
1139 */
8c427226 1140 if (!(ass & 0x8000))
c9b58006
KY
1141 return;
1142 /*
1143 * 10~8 : Jack location
1144 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1145 * 14~13: Resvered
1146 * 15 : 1 --> enable the function "Mute internal speaker
1147 * when the external headphone out jack is plugged"
1148 */
1149 if (!spec->autocfg.speaker_pins[0]) {
8c427226 1150 if (spec->autocfg.line_out_pins[0])
c9b58006 1151 spec->autocfg.speaker_pins[0] =
8c427226 1152 spec->autocfg.line_out_pins[0];
c9b58006
KY
1153 else
1154 return;
1155 }
1156
1157 if (!spec->autocfg.hp_pins[0]) {
1158 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1159 if (tmp == 0)
1160 spec->autocfg.hp_pins[0] = porta;
1161 else if (tmp == 1)
1162 spec->autocfg.hp_pins[0] = porte;
1163 else if (tmp == 2)
1164 spec->autocfg.hp_pins[0] = portd;
1165 else
1166 return;
1167 }
7fb0d78f
KY
1168 if (spec->autocfg.hp_pins[0])
1169 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1170 AC_VERB_SET_UNSOLICITED_ENABLE,
1171 AC_USRSP_EN | ALC880_HP_EVENT);
c9b58006 1172
4605b718 1173#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
1174 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1175 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1176 snd_hda_codec_write(codec,
1177 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1178 AC_VERB_SET_UNSOLICITED_ENABLE,
1179 AC_USRSP_EN | ALC880_MIC_EVENT);
4605b718 1180#endif /* disabled */
ea1fb29a 1181
c9b58006 1182 spec->unsol_event = alc_sku_unsol_event;
bc9f98a9
KY
1183}
1184
f95474ec
TI
1185/*
1186 * Fix-up pin default configurations
1187 */
1188
1189struct alc_pincfg {
1190 hda_nid_t nid;
1191 u32 val;
1192};
1193
1194static void alc_fix_pincfg(struct hda_codec *codec,
1195 const struct snd_pci_quirk *quirk,
1196 const struct alc_pincfg **pinfix)
1197{
1198 const struct alc_pincfg *cfg;
1199
1200 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1201 if (!quirk)
1202 return;
1203
1204 cfg = pinfix[quirk->value];
0e8a21b5
TI
1205 for (; cfg->nid; cfg++)
1206 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
f95474ec
TI
1207}
1208
ef8ef5fb
VP
1209/*
1210 * ALC888
1211 */
1212
1213/*
1214 * 2ch mode
1215 */
1216static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1217/* Mic-in jack as mic in */
1218 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1219 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1220/* Line-in jack as Line in */
1221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1223/* Line-Out as Front */
1224 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1225 { } /* end */
1226};
1227
1228/*
1229 * 4ch mode
1230 */
1231static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1232/* Mic-in jack as mic in */
1233 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1234 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1235/* Line-in jack as Surround */
1236 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1237 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1238/* Line-Out as Front */
1239 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1240 { } /* end */
1241};
1242
1243/*
1244 * 6ch mode
1245 */
1246static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1247/* Mic-in jack as CLFE */
1248 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1249 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1250/* Line-in jack as Surround */
1251 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1252 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1253/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1254 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1255 { } /* end */
1256};
1257
1258/*
1259 * 8ch mode
1260 */
1261static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1262/* Mic-in jack as CLFE */
1263 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1264 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1265/* Line-in jack as Surround */
1266 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1267 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1268/* Line-Out as Side */
1269 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1270 { } /* end */
1271};
1272
1273static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1274 { 2, alc888_4ST_ch2_intel_init },
1275 { 4, alc888_4ST_ch4_intel_init },
1276 { 6, alc888_4ST_ch6_intel_init },
1277 { 8, alc888_4ST_ch8_intel_init },
1278};
1279
1280/*
1281 * ALC888 Fujitsu Siemens Amillo xa3530
1282 */
1283
1284static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1285/* Front Mic: set to PIN_IN (empty by default) */
1286 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1287/* Connect Internal HP to Front */
1288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1290 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1291/* Connect Bass HP to Front */
1292 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1293 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1294 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1295/* Connect Line-Out side jack (SPDIF) to Side */
1296 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1299/* Connect Mic jack to CLFE */
1300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1301 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1302 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1303/* Connect Line-in jack to Surround */
1304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1306 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1307/* Connect HP out jack to Front */
1308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1311/* Enable unsolicited event for HP jack and Line-out jack */
1312 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1313 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1314 {}
1315};
1316
1317static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1318{
1319 unsigned int present;
1320 unsigned int bits;
1321 /* Line out presence */
1322 present = snd_hda_codec_read(codec, 0x17, 0,
1323 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1324 /* HP out presence */
1325 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1326 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1327 bits = present ? HDA_AMP_MUTE : 0;
1328 /* Toggle internal speakers muting */
1329 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1330 HDA_AMP_MUTE, bits);
1331 /* Toggle internal bass muting */
1332 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1333 HDA_AMP_MUTE, bits);
1334}
1335
1336static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1337 unsigned int res)
1338{
1339 if (res >> 26 == ALC880_HP_EVENT)
1340 alc888_fujitsu_xa3530_automute(codec);
1341}
1342
1343
5b2d1eca
VP
1344/*
1345 * ALC888 Acer Aspire 4930G model
1346 */
1347
1348static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1349/* Front Mic: set to PIN_IN (empty by default) */
1350 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1351/* Unselect Front Mic by default in input mixer 3 */
1352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1353/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1354 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1355/* Connect Internal HP to front */
1356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1359/* Connect HP out to front */
1360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1363 { }
1364};
1365
ef8ef5fb 1366static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1367 /* Front mic only available on one ADC */
1368 {
1369 .num_items = 4,
1370 .items = {
1371 { "Mic", 0x0 },
1372 { "Line", 0x2 },
1373 { "CD", 0x4 },
1374 { "Front Mic", 0xb },
1375 },
1376 },
1377 {
1378 .num_items = 3,
1379 .items = {
1380 { "Mic", 0x0 },
1381 { "Line", 0x2 },
1382 { "CD", 0x4 },
1383 },
1384 }
1385};
1386
ef8ef5fb 1387static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1390 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1391 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1392 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1393 HDA_OUTPUT),
1394 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1395 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1396 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1397 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1398 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1406 { } /* end */
1407};
1408
1409static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1410{
1411 unsigned int present;
ef8ef5fb 1412 unsigned int bits;
5b2d1eca
VP
1413 present = snd_hda_codec_read(codec, 0x15, 0,
1414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
ef8ef5fb
VP
1415 bits = present ? HDA_AMP_MUTE : 0;
1416 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1417 HDA_AMP_MUTE, bits);
5b2d1eca
VP
1418}
1419
1420static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1421 unsigned int res)
1422{
1423 if (res >> 26 == ALC880_HP_EVENT)
1424 alc888_acer_aspire_4930g_automute(codec);
1425}
1426
1da177e4 1427/*
e9edcee0
TI
1428 * ALC880 3-stack model
1429 *
1430 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1431 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1432 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1433 */
1434
e9edcee0
TI
1435static hda_nid_t alc880_dac_nids[4] = {
1436 /* front, rear, clfe, rear_surr */
1437 0x02, 0x05, 0x04, 0x03
1438};
1439
1440static hda_nid_t alc880_adc_nids[3] = {
1441 /* ADC0-2 */
1442 0x07, 0x08, 0x09,
1443};
1444
1445/* The datasheet says the node 0x07 is connected from inputs,
1446 * but it shows zero connection in the real implementation on some devices.
df694daa 1447 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1448 */
e9edcee0
TI
1449static hda_nid_t alc880_adc_nids_alt[2] = {
1450 /* ADC1-2 */
1451 0x08, 0x09,
1452};
1453
1454#define ALC880_DIGOUT_NID 0x06
1455#define ALC880_DIGIN_NID 0x0a
1456
1457static struct hda_input_mux alc880_capture_source = {
1458 .num_items = 4,
1459 .items = {
1460 { "Mic", 0x0 },
1461 { "Front Mic", 0x3 },
1462 { "Line", 0x2 },
1463 { "CD", 0x4 },
1464 },
1465};
1466
1467/* channel source setting (2/6 channel selection for 3-stack) */
1468/* 2ch mode */
1469static struct hda_verb alc880_threestack_ch2_init[] = {
1470 /* set line-in to input, mute it */
1471 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1472 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1473 /* set mic-in to input vref 80%, mute it */
1474 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1475 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1476 { } /* end */
1477};
1478
1479/* 6ch mode */
1480static struct hda_verb alc880_threestack_ch6_init[] = {
1481 /* set line-in to output, unmute it */
1482 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1483 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1484 /* set mic-in to output, unmute it */
1485 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1486 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1487 { } /* end */
1488};
1489
d2a6d7dc 1490static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1491 { 2, alc880_threestack_ch2_init },
1492 { 6, alc880_threestack_ch6_init },
1493};
1494
c8b6bf9b 1495static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1496 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1498 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1499 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1500 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1501 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1502 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1503 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1511 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1513 {
1514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1515 .name = "Channel Mode",
df694daa
KY
1516 .info = alc_ch_mode_info,
1517 .get = alc_ch_mode_get,
1518 .put = alc_ch_mode_put,
e9edcee0
TI
1519 },
1520 { } /* end */
1521};
1522
1523/* capture mixer elements */
f9e336f6
TI
1524static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1525 struct snd_ctl_elem_info *uinfo)
1526{
1527 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1528 struct alc_spec *spec = codec->spec;
1529 int err;
1da177e4 1530
5a9e02e9 1531 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1532 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1533 HDA_INPUT);
1534 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1535 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1536 return err;
1537}
1538
1539static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1540 unsigned int size, unsigned int __user *tlv)
1541{
1542 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1543 struct alc_spec *spec = codec->spec;
1544 int err;
1da177e4 1545
5a9e02e9 1546 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1547 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1548 HDA_INPUT);
1549 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1550 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1551 return err;
1552}
1553
1554typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1555 struct snd_ctl_elem_value *ucontrol);
1556
1557static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1558 struct snd_ctl_elem_value *ucontrol,
1559 getput_call_t func)
1560{
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 struct alc_spec *spec = codec->spec;
1563 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1564 int err;
1565
5a9e02e9 1566 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1567 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1568 3, 0, HDA_INPUT);
1569 err = func(kcontrol, ucontrol);
5a9e02e9 1570 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1571 return err;
1572}
1573
1574static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1575 struct snd_ctl_elem_value *ucontrol)
1576{
1577 return alc_cap_getput_caller(kcontrol, ucontrol,
1578 snd_hda_mixer_amp_volume_get);
1579}
1580
1581static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1582 struct snd_ctl_elem_value *ucontrol)
1583{
1584 return alc_cap_getput_caller(kcontrol, ucontrol,
1585 snd_hda_mixer_amp_volume_put);
1586}
1587
1588/* capture mixer elements */
1589#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1590
1591static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1592 struct snd_ctl_elem_value *ucontrol)
1593{
1594 return alc_cap_getput_caller(kcontrol, ucontrol,
1595 snd_hda_mixer_amp_switch_get);
1596}
1597
1598static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1599 struct snd_ctl_elem_value *ucontrol)
1600{
1601 return alc_cap_getput_caller(kcontrol, ucontrol,
1602 snd_hda_mixer_amp_switch_put);
1603}
1604
a23b688f 1605#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
1606 { \
1607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1608 .name = "Capture Switch", \
1609 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1610 .count = num, \
1611 .info = alc_cap_sw_info, \
1612 .get = alc_cap_sw_get, \
1613 .put = alc_cap_sw_put, \
1614 }, \
1615 { \
1616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1617 .name = "Capture Volume", \
1618 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1619 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1620 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1621 .count = num, \
1622 .info = alc_cap_vol_info, \
1623 .get = alc_cap_vol_get, \
1624 .put = alc_cap_vol_put, \
1625 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
1626 }
1627
1628#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
1629 { \
1630 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1631 /* .name = "Capture Source", */ \
1632 .name = "Input Source", \
1633 .count = num, \
1634 .info = alc_mux_enum_info, \
1635 .get = alc_mux_enum_get, \
1636 .put = alc_mux_enum_put, \
a23b688f
TI
1637 }
1638
1639#define DEFINE_CAPMIX(num) \
1640static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1641 _DEFINE_CAPMIX(num), \
1642 _DEFINE_CAPSRC(num), \
1643 { } /* end */ \
1644}
1645
1646#define DEFINE_CAPMIX_NOSRC(num) \
1647static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1648 _DEFINE_CAPMIX(num), \
1649 { } /* end */ \
f9e336f6
TI
1650}
1651
1652/* up to three ADCs */
1653DEFINE_CAPMIX(1);
1654DEFINE_CAPMIX(2);
1655DEFINE_CAPMIX(3);
a23b688f
TI
1656DEFINE_CAPMIX_NOSRC(1);
1657DEFINE_CAPMIX_NOSRC(2);
1658DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
1659
1660/*
1661 * ALC880 5-stack model
1662 *
9c7f852e
TI
1663 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1664 * Side = 0x02 (0xd)
e9edcee0
TI
1665 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1666 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1667 */
1668
1669/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1670static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1671 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1672 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1673 { } /* end */
1674};
1675
e9edcee0
TI
1676/* channel source setting (6/8 channel selection for 5-stack) */
1677/* 6ch mode */
1678static struct hda_verb alc880_fivestack_ch6_init[] = {
1679 /* set line-in to input, mute it */
1680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1682 { } /* end */
1683};
1684
e9edcee0
TI
1685/* 8ch mode */
1686static struct hda_verb alc880_fivestack_ch8_init[] = {
1687 /* set line-in to output, unmute it */
1688 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1689 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1690 { } /* end */
1691};
1692
d2a6d7dc 1693static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1694 { 6, alc880_fivestack_ch6_init },
1695 { 8, alc880_fivestack_ch8_init },
1696};
1697
1698
1699/*
1700 * ALC880 6-stack model
1701 *
9c7f852e
TI
1702 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1703 * Side = 0x05 (0x0f)
e9edcee0
TI
1704 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1705 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1706 */
1707
1708static hda_nid_t alc880_6st_dac_nids[4] = {
1709 /* front, rear, clfe, rear_surr */
1710 0x02, 0x03, 0x04, 0x05
f12ab1e0 1711};
e9edcee0
TI
1712
1713static struct hda_input_mux alc880_6stack_capture_source = {
1714 .num_items = 4,
1715 .items = {
1716 { "Mic", 0x0 },
1717 { "Front Mic", 0x1 },
1718 { "Line", 0x2 },
1719 { "CD", 0x4 },
1720 },
1721};
1722
1723/* fixed 8-channels */
d2a6d7dc 1724static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1725 { 8, NULL },
1726};
1727
c8b6bf9b 1728static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1729 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1730 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1731 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1732 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1733 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1734 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1735 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1736 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1737 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1738 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1739 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1740 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1741 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1742 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1746 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
1747 {
1748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1749 .name = "Channel Mode",
df694daa
KY
1750 .info = alc_ch_mode_info,
1751 .get = alc_ch_mode_get,
1752 .put = alc_ch_mode_put,
16ded525
TI
1753 },
1754 { } /* end */
1755};
1756
e9edcee0
TI
1757
1758/*
1759 * ALC880 W810 model
1760 *
1761 * W810 has rear IO for:
1762 * Front (DAC 02)
1763 * Surround (DAC 03)
1764 * Center/LFE (DAC 04)
1765 * Digital out (06)
1766 *
1767 * The system also has a pair of internal speakers, and a headphone jack.
1768 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 1769 *
e9edcee0
TI
1770 * There is a variable resistor to control the speaker or headphone
1771 * volume. This is a hardware-only device without a software API.
1772 *
1773 * Plugging headphones in will disable the internal speakers. This is
1774 * implemented in hardware, not via the driver using jack sense. In
1775 * a similar fashion, plugging into the rear socket marked "front" will
1776 * disable both the speakers and headphones.
1777 *
1778 * For input, there's a microphone jack, and an "audio in" jack.
1779 * These may not do anything useful with this driver yet, because I
1780 * haven't setup any initialization verbs for these yet...
1781 */
1782
1783static hda_nid_t alc880_w810_dac_nids[3] = {
1784 /* front, rear/surround, clfe */
1785 0x02, 0x03, 0x04
16ded525
TI
1786};
1787
e9edcee0 1788/* fixed 6 channels */
d2a6d7dc 1789static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1790 { 6, NULL }
1791};
1792
1793/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1794static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1795 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1796 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1797 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1798 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1799 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1804 { } /* end */
1805};
1806
1807
1808/*
1809 * Z710V model
1810 *
1811 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1812 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1813 * Line = 0x1a
e9edcee0
TI
1814 */
1815
1816static hda_nid_t alc880_z71v_dac_nids[1] = {
1817 0x02
1818};
1819#define ALC880_Z71V_HP_DAC 0x03
1820
1821/* fixed 2 channels */
d2a6d7dc 1822static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1823 { 2, NULL }
1824};
1825
c8b6bf9b 1826static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1830 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1835 { } /* end */
1836};
1837
e9edcee0 1838
e9edcee0
TI
1839/*
1840 * ALC880 F1734 model
1841 *
1842 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1843 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1844 */
1845
1846static hda_nid_t alc880_f1734_dac_nids[1] = {
1847 0x03
1848};
1849#define ALC880_F1734_HP_DAC 0x02
1850
c8b6bf9b 1851static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1854 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1855 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1860 { } /* end */
1861};
1862
937b4160
TI
1863static struct hda_input_mux alc880_f1734_capture_source = {
1864 .num_items = 2,
1865 .items = {
1866 { "Mic", 0x1 },
1867 { "CD", 0x4 },
1868 },
1869};
1870
e9edcee0 1871
e9edcee0
TI
1872/*
1873 * ALC880 ASUS model
1874 *
1875 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1876 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1877 * Mic = 0x18, Line = 0x1a
1878 */
1879
1880#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1881#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1882
c8b6bf9b 1883static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1885 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1886 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1887 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1894 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1895 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1898 {
1899 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1900 .name = "Channel Mode",
df694daa
KY
1901 .info = alc_ch_mode_info,
1902 .get = alc_ch_mode_get,
1903 .put = alc_ch_mode_put,
16ded525
TI
1904 },
1905 { } /* end */
1906};
e9edcee0 1907
e9edcee0
TI
1908/*
1909 * ALC880 ASUS W1V model
1910 *
1911 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1912 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1913 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1914 */
1915
1916/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1917static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1918 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1919 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1920 { } /* end */
1921};
1922
df694daa
KY
1923/* TCL S700 */
1924static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1926 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1928 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1929 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1932 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1933 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
1934 { } /* end */
1935};
1936
ccc656ce
KY
1937/* Uniwill */
1938static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1939 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1940 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1941 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1942 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1949 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1950 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1952 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1953 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1954 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
1955 {
1956 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1957 .name = "Channel Mode",
1958 .info = alc_ch_mode_info,
1959 .get = alc_ch_mode_get,
1960 .put = alc_ch_mode_put,
1961 },
1962 { } /* end */
1963};
1964
2cf9f0fc
TD
1965static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1966 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1968 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1969 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1970 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1971 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1973 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1974 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1975 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1976 { } /* end */
1977};
1978
ccc656ce 1979static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1980 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1981 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1982 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1983 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1986 { } /* end */
1987};
1988
2134ea4f
TI
1989/*
1990 * virtual master controls
1991 */
1992
1993/*
1994 * slave controls for virtual master
1995 */
1996static const char *alc_slave_vols[] = {
1997 "Front Playback Volume",
1998 "Surround Playback Volume",
1999 "Center Playback Volume",
2000 "LFE Playback Volume",
2001 "Side Playback Volume",
2002 "Headphone Playback Volume",
2003 "Speaker Playback Volume",
2004 "Mono Playback Volume",
2134ea4f 2005 "Line-Out Playback Volume",
26f5df26 2006 "PCM Playback Volume",
2134ea4f
TI
2007 NULL,
2008};
2009
2010static const char *alc_slave_sws[] = {
2011 "Front Playback Switch",
2012 "Surround Playback Switch",
2013 "Center Playback Switch",
2014 "LFE Playback Switch",
2015 "Side Playback Switch",
2016 "Headphone Playback Switch",
2017 "Speaker Playback Switch",
2018 "Mono Playback Switch",
edb54a55 2019 "IEC958 Playback Switch",
2134ea4f
TI
2020 NULL,
2021};
2022
1da177e4 2023/*
e9edcee0 2024 * build control elements
1da177e4 2025 */
603c4019
TI
2026
2027static void alc_free_kctls(struct hda_codec *codec);
2028
45bdd1c1
TI
2029/* additional beep mixers; the actual parameters are overwritten at build */
2030static struct snd_kcontrol_new alc_beep_mixer[] = {
2031 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2032 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2033 { } /* end */
2034};
2035
1da177e4
LT
2036static int alc_build_controls(struct hda_codec *codec)
2037{
2038 struct alc_spec *spec = codec->spec;
2039 int err;
2040 int i;
2041
2042 for (i = 0; i < spec->num_mixers; i++) {
2043 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2044 if (err < 0)
2045 return err;
2046 }
f9e336f6
TI
2047 if (spec->cap_mixer) {
2048 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2049 if (err < 0)
2050 return err;
2051 }
1da177e4 2052 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2053 err = snd_hda_create_spdif_out_ctls(codec,
2054 spec->multiout.dig_out_nid);
1da177e4
LT
2055 if (err < 0)
2056 return err;
e64f14f4
TI
2057 if (!spec->no_analog) {
2058 err = snd_hda_create_spdif_share_sw(codec,
2059 &spec->multiout);
2060 if (err < 0)
2061 return err;
2062 spec->multiout.share_spdif = 1;
2063 }
1da177e4
LT
2064 }
2065 if (spec->dig_in_nid) {
2066 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2067 if (err < 0)
2068 return err;
2069 }
2134ea4f 2070
45bdd1c1
TI
2071 /* create beep controls if needed */
2072 if (spec->beep_amp) {
2073 struct snd_kcontrol_new *knew;
2074 for (knew = alc_beep_mixer; knew->name; knew++) {
2075 struct snd_kcontrol *kctl;
2076 kctl = snd_ctl_new1(knew, codec);
2077 if (!kctl)
2078 return -ENOMEM;
2079 kctl->private_value = spec->beep_amp;
2080 err = snd_hda_ctl_add(codec, kctl);
2081 if (err < 0)
2082 return err;
2083 }
2084 }
2085
2134ea4f 2086 /* if we have no master control, let's create it */
e64f14f4
TI
2087 if (!spec->no_analog &&
2088 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2089 unsigned int vmaster_tlv[4];
2134ea4f 2090 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2091 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2092 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2093 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2094 if (err < 0)
2095 return err;
2096 }
e64f14f4
TI
2097 if (!spec->no_analog &&
2098 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2099 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2100 NULL, alc_slave_sws);
2101 if (err < 0)
2102 return err;
2103 }
2104
603c4019 2105 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
2106 return 0;
2107}
2108
e9edcee0 2109
1da177e4
LT
2110/*
2111 * initialize the codec volumes, etc
2112 */
2113
e9edcee0
TI
2114/*
2115 * generic initialization of ADC, input mixers and output mixers
2116 */
2117static struct hda_verb alc880_volume_init_verbs[] = {
2118 /*
2119 * Unmute ADC0-2 and set the default input to mic-in
2120 */
71fe7b82 2121 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2122 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2123 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2125 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2127
e9edcee0
TI
2128 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2129 * mixer widget
9c7f852e
TI
2130 * Note: PASD motherboards uses the Line In 2 as the input for front
2131 * panel mic (mic 2)
1da177e4 2132 */
e9edcee0 2133 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2141
e9edcee0
TI
2142 /*
2143 * Set up output mixers (0x0c - 0x0f)
1da177e4 2144 */
e9edcee0
TI
2145 /* set vol=0 to output mixers */
2146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2147 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2148 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2149 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2150 /* set up input amps for analog loopback */
2151 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2152 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2153 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2154 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2156 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2157 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2158 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2159 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2160
2161 { }
2162};
2163
e9edcee0
TI
2164/*
2165 * 3-stack pin configuration:
2166 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2167 */
2168static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2169 /*
2170 * preset connection lists of input pins
2171 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2172 */
2173 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2176
2177 /*
2178 * Set pin mode and muting
2179 */
2180 /* set front pin widgets 0x14 for output */
05acb863 2181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2182 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2183 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2184 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2185 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2186 /* Mic2 (as headphone out) for HP output */
2187 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2188 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2189 /* Line In pin widget for input */
05acb863 2190 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2191 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2192 /* Line2 (as front mic) pin widget for input and vref at 80% */
2193 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2194 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2195 /* CD pin widget for input */
05acb863 2196 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2197
e9edcee0
TI
2198 { }
2199};
1da177e4 2200
e9edcee0
TI
2201/*
2202 * 5-stack pin configuration:
2203 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2204 * line-in/side = 0x1a, f-mic = 0x1b
2205 */
2206static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2207 /*
2208 * preset connection lists of input pins
2209 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2210 */
e9edcee0
TI
2211 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2212 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2213
e9edcee0
TI
2214 /*
2215 * Set pin mode and muting
1da177e4 2216 */
e9edcee0
TI
2217 /* set pin widgets 0x14-0x17 for output */
2218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2221 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 /* unmute pins for output (no gain on this amp) */
2223 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227
2228 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2229 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2230 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2231 /* Mic2 (as headphone out) for HP output */
2232 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2233 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234 /* Line In pin widget for input */
2235 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2236 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2237 /* Line2 (as front mic) pin widget for input and vref at 80% */
2238 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2239 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2240 /* CD pin widget for input */
2241 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2242
2243 { }
2244};
2245
e9edcee0
TI
2246/*
2247 * W810 pin configuration:
2248 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2249 */
2250static struct hda_verb alc880_pin_w810_init_verbs[] = {
2251 /* hphone/speaker input selector: front DAC */
2252 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2253
05acb863 2254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2258 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2260
e9edcee0 2261 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2262 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2263
1da177e4
LT
2264 { }
2265};
2266
e9edcee0
TI
2267/*
2268 * Z71V pin configuration:
2269 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2270 */
2271static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2272 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2273 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2275 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2276
16ded525 2277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2279 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2280 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2281
2282 { }
2283};
2284
e9edcee0
TI
2285/*
2286 * 6-stack pin configuration:
9c7f852e
TI
2287 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2288 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2289 */
2290static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2291 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2292
16ded525 2293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2296 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2297 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2298 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2300 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2301
16ded525 2302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2303 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2305 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2306 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2307 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2311
e9edcee0
TI
2312 { }
2313};
2314
ccc656ce
KY
2315/*
2316 * Uniwill pin configuration:
2317 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2318 * line = 0x1a
2319 */
2320static struct hda_verb alc880_uniwill_init_verbs[] = {
2321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2322
2323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2328 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2329 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2330 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2337
2338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2342 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2344 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2345 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2346 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2347
2348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2349 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2350
2351 { }
2352};
2353
2354/*
2355* Uniwill P53
ea1fb29a 2356* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2357 */
2358static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2359 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2360
2361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2364 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2373
2374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2376 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2377 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2378 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2380
2381 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2382 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2383
2384 { }
2385};
2386
2cf9f0fc
TD
2387static struct hda_verb alc880_beep_init_verbs[] = {
2388 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2389 { }
2390};
2391
ccc656ce 2392/* toggle speaker-output according to the hp-jack state */
458a4fab 2393static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
2394{
2395 unsigned int present;
f12ab1e0 2396 unsigned char bits;
ccc656ce
KY
2397
2398 present = snd_hda_codec_read(codec, 0x14, 0,
2399 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2400 bits = present ? HDA_AMP_MUTE : 0;
2401 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2402 HDA_AMP_MUTE, bits);
2403 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2404 HDA_AMP_MUTE, bits);
458a4fab
TI
2405}
2406
2407/* auto-toggle front mic */
2408static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2409{
2410 unsigned int present;
2411 unsigned char bits;
ccc656ce
KY
2412
2413 present = snd_hda_codec_read(codec, 0x18, 0,
2414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2415 bits = present ? HDA_AMP_MUTE : 0;
2416 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2417}
2418
2419static void alc880_uniwill_automute(struct hda_codec *codec)
2420{
2421 alc880_uniwill_hp_automute(codec);
2422 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2423}
2424
2425static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2426 unsigned int res)
2427{
2428 /* Looks like the unsol event is incompatible with the standard
2429 * definition. 4bit tag is placed at 28 bit!
2430 */
458a4fab
TI
2431 switch (res >> 28) {
2432 case ALC880_HP_EVENT:
2433 alc880_uniwill_hp_automute(codec);
2434 break;
2435 case ALC880_MIC_EVENT:
2436 alc880_uniwill_mic_automute(codec);
2437 break;
2438 }
ccc656ce
KY
2439}
2440
2441static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2442{
2443 unsigned int present;
f12ab1e0 2444 unsigned char bits;
ccc656ce
KY
2445
2446 present = snd_hda_codec_read(codec, 0x14, 0,
2447 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a 2448 bits = present ? HDA_AMP_MUTE : 0;
64654c2f 2449 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
2450}
2451
2452static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2453{
2454 unsigned int present;
ea1fb29a 2455
ccc656ce 2456 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2457 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2458 present &= HDA_AMP_VOLMASK;
2459 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2460 HDA_AMP_VOLMASK, present);
2461 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2462 HDA_AMP_VOLMASK, present);
ccc656ce 2463}
47fd830a 2464
ccc656ce
KY
2465static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2466 unsigned int res)
2467{
2468 /* Looks like the unsol event is incompatible with the standard
2469 * definition. 4bit tag is placed at 28 bit!
2470 */
2471 if ((res >> 28) == ALC880_HP_EVENT)
2472 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 2473 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
2474 alc880_uniwill_p53_dcvol_automute(codec);
2475}
2476
e9edcee0
TI
2477/*
2478 * F1734 pin configuration:
2479 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2480 */
2481static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2483 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2484 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2485 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2486 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2487
e9edcee0 2488 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2490 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2491 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2492
e9edcee0
TI
2493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2495 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2496 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2499 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2500 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2502
937b4160
TI
2503 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2504 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2505
dfc0ff62
TI
2506 { }
2507};
2508
e9edcee0
TI
2509/*
2510 * ASUS pin configuration:
2511 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2512 */
2513static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2514 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2515 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2516 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2517 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2518
2519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2525 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2527
2528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2537
e9edcee0
TI
2538 { }
2539};
16ded525 2540
e9edcee0 2541/* Enable GPIO mask and set output */
bc9f98a9
KY
2542#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2543#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
2544
2545/* Clevo m520g init */
2546static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2547 /* headphone output */
2548 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2549 /* line-out */
2550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2552 /* Line-in */
2553 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 /* CD */
2556 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2557 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2558 /* Mic1 (rear panel) */
2559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2561 /* Mic2 (front panel) */
2562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2563 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2564 /* headphone */
2565 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2567 /* change to EAPD mode */
2568 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2569 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2570
2571 { }
16ded525
TI
2572};
2573
df694daa 2574static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2575 /* change to EAPD mode */
2576 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2577 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2578
df694daa
KY
2579 /* Headphone output */
2580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2581 /* Front output*/
2582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2583 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2584
2585 /* Line In pin widget for input */
2586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2587 /* CD pin widget for input */
2588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2589 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2591
2592 /* change to EAPD mode */
2593 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2594 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2595
2596 { }
2597};
16ded525 2598
e9edcee0 2599/*
ae6b813a
TI
2600 * LG m1 express dual
2601 *
2602 * Pin assignment:
2603 * Rear Line-In/Out (blue): 0x14
2604 * Build-in Mic-In: 0x15
2605 * Speaker-out: 0x17
2606 * HP-Out (green): 0x1b
2607 * Mic-In/Out (red): 0x19
2608 * SPDIF-Out: 0x1e
2609 */
2610
2611/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2612static hda_nid_t alc880_lg_dac_nids[3] = {
2613 0x05, 0x02, 0x03
2614};
2615
2616/* seems analog CD is not working */
2617static struct hda_input_mux alc880_lg_capture_source = {
2618 .num_items = 3,
2619 .items = {
2620 { "Mic", 0x1 },
2621 { "Line", 0x5 },
2622 { "Internal Mic", 0x6 },
2623 },
2624};
2625
2626/* 2,4,6 channel modes */
2627static struct hda_verb alc880_lg_ch2_init[] = {
2628 /* set line-in and mic-in to input */
2629 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2630 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2631 { }
2632};
2633
2634static struct hda_verb alc880_lg_ch4_init[] = {
2635 /* set line-in to out and mic-in to input */
2636 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2637 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2638 { }
2639};
2640
2641static struct hda_verb alc880_lg_ch6_init[] = {
2642 /* set line-in and mic-in to output */
2643 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2644 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2645 { }
2646};
2647
2648static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2649 { 2, alc880_lg_ch2_init },
2650 { 4, alc880_lg_ch4_init },
2651 { 6, alc880_lg_ch6_init },
2652};
2653
2654static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2656 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2658 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2661 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2662 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2668 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2669 {
2670 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2671 .name = "Channel Mode",
2672 .info = alc_ch_mode_info,
2673 .get = alc_ch_mode_get,
2674 .put = alc_ch_mode_put,
2675 },
2676 { } /* end */
2677};
2678
2679static struct hda_verb alc880_lg_init_verbs[] = {
2680 /* set capture source to mic-in */
2681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2682 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2684 /* mute all amp mixer inputs */
2685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2688 /* line-in to input */
2689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2691 /* built-in mic */
2692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2694 /* speaker-out */
2695 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2696 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2697 /* mic-in to input */
2698 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2699 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2700 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2701 /* HP-out */
2702 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2703 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2704 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2705 /* jack sense */
2706 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2707 { }
2708};
2709
2710/* toggle speaker-output according to the hp-jack state */
2711static void alc880_lg_automute(struct hda_codec *codec)
2712{
2713 unsigned int present;
f12ab1e0 2714 unsigned char bits;
ae6b813a
TI
2715
2716 present = snd_hda_codec_read(codec, 0x1b, 0,
2717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2718 bits = present ? HDA_AMP_MUTE : 0;
2719 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2720 HDA_AMP_MUTE, bits);
ae6b813a
TI
2721}
2722
2723static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2724{
2725 /* Looks like the unsol event is incompatible with the standard
2726 * definition. 4bit tag is placed at 28 bit!
2727 */
2728 if ((res >> 28) == 0x01)
2729 alc880_lg_automute(codec);
2730}
2731
d681518a
TI
2732/*
2733 * LG LW20
2734 *
2735 * Pin assignment:
2736 * Speaker-out: 0x14
2737 * Mic-In: 0x18
e4f41da9
CM
2738 * Built-in Mic-In: 0x19
2739 * Line-In: 0x1b
2740 * HP-Out: 0x1a
d681518a
TI
2741 * SPDIF-Out: 0x1e
2742 */
2743
d681518a 2744static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2745 .num_items = 3,
d681518a
TI
2746 .items = {
2747 { "Mic", 0x0 },
2748 { "Internal Mic", 0x1 },
e4f41da9 2749 { "Line In", 0x2 },
d681518a
TI
2750 },
2751};
2752
0a8c5da3
CM
2753#define alc880_lg_lw_modes alc880_threestack_modes
2754
d681518a 2755static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2759 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2760 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2761 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2762 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2763 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2768 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2769 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2770 {
2771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2772 .name = "Channel Mode",
2773 .info = alc_ch_mode_info,
2774 .get = alc_ch_mode_get,
2775 .put = alc_ch_mode_put,
2776 },
d681518a
TI
2777 { } /* end */
2778};
2779
2780static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2781 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2782 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2783 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2784
d681518a
TI
2785 /* set capture source to mic-in */
2786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2790 /* speaker-out */
2791 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2793 /* HP-out */
d681518a
TI
2794 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2795 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 /* mic-in to input */
2797 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2799 /* built-in mic */
2800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802 /* jack sense */
2803 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2804 { }
2805};
2806
2807/* toggle speaker-output according to the hp-jack state */
2808static void alc880_lg_lw_automute(struct hda_codec *codec)
2809{
2810 unsigned int present;
f12ab1e0 2811 unsigned char bits;
d681518a
TI
2812
2813 present = snd_hda_codec_read(codec, 0x1b, 0,
2814 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2815 bits = present ? HDA_AMP_MUTE : 0;
2816 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2817 HDA_AMP_MUTE, bits);
d681518a
TI
2818}
2819
2820static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2821{
2822 /* Looks like the unsol event is incompatible with the standard
2823 * definition. 4bit tag is placed at 28 bit!
2824 */
2825 if ((res >> 28) == 0x01)
2826 alc880_lg_lw_automute(codec);
2827}
2828
df99cd33
TI
2829static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2830 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2831 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2834 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2835 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2836 { } /* end */
2837};
2838
2839static struct hda_input_mux alc880_medion_rim_capture_source = {
2840 .num_items = 2,
2841 .items = {
2842 { "Mic", 0x0 },
2843 { "Internal Mic", 0x1 },
2844 },
2845};
2846
2847static struct hda_verb alc880_medion_rim_init_verbs[] = {
2848 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2849
2850 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2852
2853 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2856 /* Mic2 (as headphone out) for HP output */
2857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2859 /* Internal Speaker */
2860 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2862
2863 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2864 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2865
2866 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2867 { }
2868};
2869
2870/* toggle speaker-output according to the hp-jack state */
2871static void alc880_medion_rim_automute(struct hda_codec *codec)
2872{
2873 unsigned int present;
2874 unsigned char bits;
2875
2876 present = snd_hda_codec_read(codec, 0x14, 0,
2877 AC_VERB_GET_PIN_SENSE, 0)
2878 & AC_PINSENSE_PRESENCE;
2879 bits = present ? HDA_AMP_MUTE : 0;
2880 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2881 HDA_AMP_MUTE, bits);
2882 if (present)
2883 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2884 else
2885 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2886}
2887
2888static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2889 unsigned int res)
2890{
2891 /* Looks like the unsol event is incompatible with the standard
2892 * definition. 4bit tag is placed at 28 bit!
2893 */
2894 if ((res >> 28) == ALC880_HP_EVENT)
2895 alc880_medion_rim_automute(codec);
2896}
2897
cb53c626
TI
2898#ifdef CONFIG_SND_HDA_POWER_SAVE
2899static struct hda_amp_list alc880_loopbacks[] = {
2900 { 0x0b, HDA_INPUT, 0 },
2901 { 0x0b, HDA_INPUT, 1 },
2902 { 0x0b, HDA_INPUT, 2 },
2903 { 0x0b, HDA_INPUT, 3 },
2904 { 0x0b, HDA_INPUT, 4 },
2905 { } /* end */
2906};
2907
2908static struct hda_amp_list alc880_lg_loopbacks[] = {
2909 { 0x0b, HDA_INPUT, 1 },
2910 { 0x0b, HDA_INPUT, 6 },
2911 { 0x0b, HDA_INPUT, 7 },
2912 { } /* end */
2913};
2914#endif
2915
ae6b813a
TI
2916/*
2917 * Common callbacks
e9edcee0
TI
2918 */
2919
1da177e4
LT
2920static int alc_init(struct hda_codec *codec)
2921{
2922 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2923 unsigned int i;
2924
2c3bf9ab 2925 alc_fix_pll(codec);
1082c748
TI
2926 if (codec->vendor_id == 0x10ec0888)
2927 alc888_coef_init(codec);
2c3bf9ab 2928
e9edcee0
TI
2929 for (i = 0; i < spec->num_init_verbs; i++)
2930 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2931
2932 if (spec->init_hook)
2933 spec->init_hook(codec);
2934
1da177e4
LT
2935 return 0;
2936}
2937
ae6b813a
TI
2938static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2939{
2940 struct alc_spec *spec = codec->spec;
2941
2942 if (spec->unsol_event)
2943 spec->unsol_event(codec, res);
2944}
2945
cb53c626
TI
2946#ifdef CONFIG_SND_HDA_POWER_SAVE
2947static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2948{
2949 struct alc_spec *spec = codec->spec;
2950 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2951}
2952#endif
2953
1da177e4
LT
2954/*
2955 * Analog playback callbacks
2956 */
2957static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2958 struct hda_codec *codec,
c8b6bf9b 2959 struct snd_pcm_substream *substream)
1da177e4
LT
2960{
2961 struct alc_spec *spec = codec->spec;
9a08160b
TI
2962 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2963 hinfo);
1da177e4
LT
2964}
2965
2966static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2967 struct hda_codec *codec,
2968 unsigned int stream_tag,
2969 unsigned int format,
c8b6bf9b 2970 struct snd_pcm_substream *substream)
1da177e4
LT
2971{
2972 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2973 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2974 stream_tag, format, substream);
1da177e4
LT
2975}
2976
2977static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2978 struct hda_codec *codec,
c8b6bf9b 2979 struct snd_pcm_substream *substream)
1da177e4
LT
2980{
2981 struct alc_spec *spec = codec->spec;
2982 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2983}
2984
2985/*
2986 * Digital out
2987 */
2988static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2989 struct hda_codec *codec,
c8b6bf9b 2990 struct snd_pcm_substream *substream)
1da177e4
LT
2991{
2992 struct alc_spec *spec = codec->spec;
2993 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2994}
2995
6b97eb45
TI
2996static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2997 struct hda_codec *codec,
2998 unsigned int stream_tag,
2999 unsigned int format,
3000 struct snd_pcm_substream *substream)
3001{
3002 struct alc_spec *spec = codec->spec;
3003 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3004 stream_tag, format, substream);
3005}
3006
9b5f12e5
TI
3007static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3008 struct hda_codec *codec,
3009 struct snd_pcm_substream *substream)
3010{
3011 struct alc_spec *spec = codec->spec;
3012 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3013}
3014
1da177e4
LT
3015static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3016 struct hda_codec *codec,
c8b6bf9b 3017 struct snd_pcm_substream *substream)
1da177e4
LT
3018{
3019 struct alc_spec *spec = codec->spec;
3020 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3021}
3022
3023/*
3024 * Analog capture
3025 */
6330079f 3026static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3027 struct hda_codec *codec,
3028 unsigned int stream_tag,
3029 unsigned int format,
c8b6bf9b 3030 struct snd_pcm_substream *substream)
1da177e4
LT
3031{
3032 struct alc_spec *spec = codec->spec;
3033
6330079f 3034 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3035 stream_tag, 0, format);
3036 return 0;
3037}
3038
6330079f 3039static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3040 struct hda_codec *codec,
c8b6bf9b 3041 struct snd_pcm_substream *substream)
1da177e4
LT
3042{
3043 struct alc_spec *spec = codec->spec;
3044
888afa15
TI
3045 snd_hda_codec_cleanup_stream(codec,
3046 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3047 return 0;
3048}
3049
3050
3051/*
3052 */
3053static struct hda_pcm_stream alc880_pcm_analog_playback = {
3054 .substreams = 1,
3055 .channels_min = 2,
3056 .channels_max = 8,
e9edcee0 3057 /* NID is set in alc_build_pcms */
1da177e4
LT
3058 .ops = {
3059 .open = alc880_playback_pcm_open,
3060 .prepare = alc880_playback_pcm_prepare,
3061 .cleanup = alc880_playback_pcm_cleanup
3062 },
3063};
3064
3065static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3066 .substreams = 1,
3067 .channels_min = 2,
3068 .channels_max = 2,
3069 /* NID is set in alc_build_pcms */
3070};
3071
3072static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3073 .substreams = 1,
3074 .channels_min = 2,
3075 .channels_max = 2,
3076 /* NID is set in alc_build_pcms */
3077};
3078
3079static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3080 .substreams = 2, /* can be overridden */
1da177e4
LT
3081 .channels_min = 2,
3082 .channels_max = 2,
e9edcee0 3083 /* NID is set in alc_build_pcms */
1da177e4 3084 .ops = {
6330079f
TI
3085 .prepare = alc880_alt_capture_pcm_prepare,
3086 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3087 },
3088};
3089
3090static struct hda_pcm_stream alc880_pcm_digital_playback = {
3091 .substreams = 1,
3092 .channels_min = 2,
3093 .channels_max = 2,
3094 /* NID is set in alc_build_pcms */
3095 .ops = {
3096 .open = alc880_dig_playback_pcm_open,
6b97eb45 3097 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3098 .prepare = alc880_dig_playback_pcm_prepare,
3099 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3100 },
3101};
3102
3103static struct hda_pcm_stream alc880_pcm_digital_capture = {
3104 .substreams = 1,
3105 .channels_min = 2,
3106 .channels_max = 2,
3107 /* NID is set in alc_build_pcms */
3108};
3109
4c5186ed 3110/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3111static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3112 .substreams = 0,
3113 .channels_min = 0,
3114 .channels_max = 0,
3115};
3116
1da177e4
LT
3117static int alc_build_pcms(struct hda_codec *codec)
3118{
3119 struct alc_spec *spec = codec->spec;
3120 struct hda_pcm *info = spec->pcm_rec;
3121 int i;
3122
3123 codec->num_pcms = 1;
3124 codec->pcm_info = info;
3125
e64f14f4
TI
3126 if (spec->no_analog)
3127 goto skip_analog;
3128
1da177e4 3129 info->name = spec->stream_name_analog;
4a471b7d 3130 if (spec->stream_analog_playback) {
da3cec35
TI
3131 if (snd_BUG_ON(!spec->multiout.dac_nids))
3132 return -EINVAL;
4a471b7d
TI
3133 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3134 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3135 }
3136 if (spec->stream_analog_capture) {
da3cec35
TI
3137 if (snd_BUG_ON(!spec->adc_nids))
3138 return -EINVAL;
4a471b7d
TI
3139 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3140 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3141 }
3142
3143 if (spec->channel_mode) {
3144 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3145 for (i = 0; i < spec->num_channel_mode; i++) {
3146 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3147 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3148 }
1da177e4
LT
3149 }
3150 }
3151
e64f14f4 3152 skip_analog:
e08a007d 3153 /* SPDIF for stream index #1 */
1da177e4 3154 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 3155 codec->num_pcms = 2;
b25c9da1 3156 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3157 info = spec->pcm_rec + 1;
1da177e4 3158 info->name = spec->stream_name_digital;
8c441982
TI
3159 if (spec->dig_out_type)
3160 info->pcm_type = spec->dig_out_type;
3161 else
3162 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3163 if (spec->multiout.dig_out_nid &&
3164 spec->stream_digital_playback) {
1da177e4
LT
3165 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3166 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3167 }
4a471b7d
TI
3168 if (spec->dig_in_nid &&
3169 spec->stream_digital_capture) {
1da177e4
LT
3170 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3171 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3172 }
963f803f
TI
3173 /* FIXME: do we need this for all Realtek codec models? */
3174 codec->spdif_status_reset = 1;
1da177e4
LT
3175 }
3176
e64f14f4
TI
3177 if (spec->no_analog)
3178 return 0;
3179
e08a007d
TI
3180 /* If the use of more than one ADC is requested for the current
3181 * model, configure a second analog capture-only PCM.
3182 */
3183 /* Additional Analaog capture for index #2 */
6330079f
TI
3184 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3185 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3186 codec->num_pcms = 3;
c06134d7 3187 info = spec->pcm_rec + 2;
e08a007d 3188 info->name = spec->stream_name_analog;
6330079f
TI
3189 if (spec->alt_dac_nid) {
3190 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3191 *spec->stream_analog_alt_playback;
3192 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3193 spec->alt_dac_nid;
3194 } else {
3195 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3196 alc_pcm_null_stream;
3197 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3198 }
3199 if (spec->num_adc_nids > 1) {
3200 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3201 *spec->stream_analog_alt_capture;
3202 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3203 spec->adc_nids[1];
3204 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3205 spec->num_adc_nids - 1;
3206 } else {
3207 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3208 alc_pcm_null_stream;
3209 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3210 }
3211 }
3212
1da177e4
LT
3213 return 0;
3214}
3215
603c4019
TI
3216static void alc_free_kctls(struct hda_codec *codec)
3217{
3218 struct alc_spec *spec = codec->spec;
3219
3220 if (spec->kctls.list) {
3221 struct snd_kcontrol_new *kctl = spec->kctls.list;
3222 int i;
3223 for (i = 0; i < spec->kctls.used; i++)
3224 kfree(kctl[i].name);
3225 }
3226 snd_array_free(&spec->kctls);
3227}
3228
1da177e4
LT
3229static void alc_free(struct hda_codec *codec)
3230{
e9edcee0 3231 struct alc_spec *spec = codec->spec;
e9edcee0 3232
f12ab1e0 3233 if (!spec)
e9edcee0
TI
3234 return;
3235
603c4019 3236 alc_free_kctls(codec);
e9edcee0 3237 kfree(spec);
680cd536 3238 snd_hda_detach_beep_device(codec);
1da177e4
LT
3239}
3240
e044c39a 3241#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3242static int alc_resume(struct hda_codec *codec)
3243{
e044c39a
TI
3244 codec->patch_ops.init(codec);
3245 snd_hda_codec_resume_amp(codec);
3246 snd_hda_codec_resume_cache(codec);
3247 return 0;
3248}
e044c39a
TI
3249#endif
3250
1da177e4
LT
3251/*
3252 */
3253static struct hda_codec_ops alc_patch_ops = {
3254 .build_controls = alc_build_controls,
3255 .build_pcms = alc_build_pcms,
3256 .init = alc_init,
3257 .free = alc_free,
ae6b813a 3258 .unsol_event = alc_unsol_event,
e044c39a
TI
3259#ifdef SND_HDA_NEEDS_RESUME
3260 .resume = alc_resume,
3261#endif
cb53c626
TI
3262#ifdef CONFIG_SND_HDA_POWER_SAVE
3263 .check_power_status = alc_check_power_status,
3264#endif
1da177e4
LT
3265};
3266
2fa522be
TI
3267
3268/*
3269 * Test configuration for debugging
3270 *
3271 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3272 * enum controls.
3273 */
3274#ifdef CONFIG_SND_DEBUG
3275static hda_nid_t alc880_test_dac_nids[4] = {
3276 0x02, 0x03, 0x04, 0x05
3277};
3278
3279static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3280 .num_items = 7,
2fa522be
TI
3281 .items = {
3282 { "In-1", 0x0 },
3283 { "In-2", 0x1 },
3284 { "In-3", 0x2 },
3285 { "In-4", 0x3 },
3286 { "CD", 0x4 },
ae6b813a
TI
3287 { "Front", 0x5 },
3288 { "Surround", 0x6 },
2fa522be
TI
3289 },
3290};
3291
d2a6d7dc 3292static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3293 { 2, NULL },
fd2c326d 3294 { 4, NULL },
2fa522be 3295 { 6, NULL },
fd2c326d 3296 { 8, NULL },
2fa522be
TI
3297};
3298
9c7f852e
TI
3299static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3300 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3301{
3302 static char *texts[] = {
3303 "N/A", "Line Out", "HP Out",
3304 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3305 };
3306 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3307 uinfo->count = 1;
3308 uinfo->value.enumerated.items = 8;
3309 if (uinfo->value.enumerated.item >= 8)
3310 uinfo->value.enumerated.item = 7;
3311 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3312 return 0;
3313}
3314
9c7f852e
TI
3315static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3316 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3317{
3318 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3319 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3320 unsigned int pin_ctl, item = 0;
3321
3322 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3323 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3324 if (pin_ctl & AC_PINCTL_OUT_EN) {
3325 if (pin_ctl & AC_PINCTL_HP_EN)
3326 item = 2;
3327 else
3328 item = 1;
3329 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3330 switch (pin_ctl & AC_PINCTL_VREFEN) {
3331 case AC_PINCTL_VREF_HIZ: item = 3; break;
3332 case AC_PINCTL_VREF_50: item = 4; break;
3333 case AC_PINCTL_VREF_GRD: item = 5; break;
3334 case AC_PINCTL_VREF_80: item = 6; break;
3335 case AC_PINCTL_VREF_100: item = 7; break;
3336 }
3337 }
3338 ucontrol->value.enumerated.item[0] = item;
3339 return 0;
3340}
3341
9c7f852e
TI
3342static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3343 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3344{
3345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3346 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3347 static unsigned int ctls[] = {
3348 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3349 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3350 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3351 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3352 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3353 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3354 };
3355 unsigned int old_ctl, new_ctl;
3356
3357 old_ctl = snd_hda_codec_read(codec, nid, 0,
3358 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3359 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3360 if (old_ctl != new_ctl) {
82beb8fd
TI
3361 int val;
3362 snd_hda_codec_write_cache(codec, nid, 0,
3363 AC_VERB_SET_PIN_WIDGET_CONTROL,
3364 new_ctl);
47fd830a
TI
3365 val = ucontrol->value.enumerated.item[0] >= 3 ?
3366 HDA_AMP_MUTE : 0;
3367 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3368 HDA_AMP_MUTE, val);
2fa522be
TI
3369 return 1;
3370 }
3371 return 0;
3372}
3373
9c7f852e
TI
3374static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3375 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3376{
3377 static char *texts[] = {
3378 "Front", "Surround", "CLFE", "Side"
3379 };
3380 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3381 uinfo->count = 1;
3382 uinfo->value.enumerated.items = 4;
3383 if (uinfo->value.enumerated.item >= 4)
3384 uinfo->value.enumerated.item = 3;
3385 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3386 return 0;
3387}
3388
9c7f852e
TI
3389static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3390 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3391{
3392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3393 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3394 unsigned int sel;
3395
3396 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3397 ucontrol->value.enumerated.item[0] = sel & 3;
3398 return 0;
3399}
3400
9c7f852e
TI
3401static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3402 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3403{
3404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3405 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3406 unsigned int sel;
3407
3408 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3409 if (ucontrol->value.enumerated.item[0] != sel) {
3410 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3411 snd_hda_codec_write_cache(codec, nid, 0,
3412 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3413 return 1;
3414 }
3415 return 0;
3416}
3417
3418#define PIN_CTL_TEST(xname,nid) { \
3419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3420 .name = xname, \
3421 .info = alc_test_pin_ctl_info, \
3422 .get = alc_test_pin_ctl_get, \
3423 .put = alc_test_pin_ctl_put, \
3424 .private_value = nid \
3425 }
3426
3427#define PIN_SRC_TEST(xname,nid) { \
3428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3429 .name = xname, \
3430 .info = alc_test_pin_src_info, \
3431 .get = alc_test_pin_src_get, \
3432 .put = alc_test_pin_src_put, \
3433 .private_value = nid \
3434 }
3435
c8b6bf9b 3436static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3437 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3438 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3439 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3440 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3441 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3442 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3443 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3444 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3445 PIN_CTL_TEST("Front Pin Mode", 0x14),
3446 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3447 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3448 PIN_CTL_TEST("Side Pin Mode", 0x17),
3449 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3450 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3451 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3452 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3453 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3454 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3455 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3456 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3457 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3458 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3459 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3460 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3461 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3462 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3463 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3464 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3465 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3466 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3467 {
3468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3469 .name = "Channel Mode",
df694daa
KY
3470 .info = alc_ch_mode_info,
3471 .get = alc_ch_mode_get,
3472 .put = alc_ch_mode_put,
2fa522be
TI
3473 },
3474 { } /* end */
3475};
3476
3477static struct hda_verb alc880_test_init_verbs[] = {
3478 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3487 /* Vol output for 0x0c-0x0f */
05acb863
TI
3488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3492 /* Set output pins 0x14-0x17 */
05acb863
TI
3493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3495 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3496 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3497 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3502 /* Set input pins 0x18-0x1c */
16ded525
TI
3503 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3507 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3508 /* Mute input pins 0x18-0x1b */
05acb863
TI
3509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3511 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3513 /* ADC set up */
05acb863 3514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3515 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3517 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3519 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3520 /* Analog input/passthru */
3521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3526 { }
3527};
3528#endif
3529
1da177e4
LT
3530/*
3531 */
3532
f5fcc13c
TI
3533static const char *alc880_models[ALC880_MODEL_LAST] = {
3534 [ALC880_3ST] = "3stack",
3535 [ALC880_TCL_S700] = "tcl",
3536 [ALC880_3ST_DIG] = "3stack-digout",
3537 [ALC880_CLEVO] = "clevo",
3538 [ALC880_5ST] = "5stack",
3539 [ALC880_5ST_DIG] = "5stack-digout",
3540 [ALC880_W810] = "w810",
3541 [ALC880_Z71V] = "z71v",
3542 [ALC880_6ST] = "6stack",
3543 [ALC880_6ST_DIG] = "6stack-digout",
3544 [ALC880_ASUS] = "asus",
3545 [ALC880_ASUS_W1V] = "asus-w1v",
3546 [ALC880_ASUS_DIG] = "asus-dig",
3547 [ALC880_ASUS_DIG2] = "asus-dig2",
3548 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3549 [ALC880_UNIWILL_P53] = "uniwill-p53",
3550 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3551 [ALC880_F1734] = "F1734",
3552 [ALC880_LG] = "lg",
3553 [ALC880_LG_LW] = "lg-lw",
df99cd33 3554 [ALC880_MEDION_RIM] = "medion",
2fa522be 3555#ifdef CONFIG_SND_DEBUG
f5fcc13c 3556 [ALC880_TEST] = "test",
2fa522be 3557#endif
f5fcc13c
TI
3558 [ALC880_AUTO] = "auto",
3559};
3560
3561static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3562 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3563 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3564 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3565 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3566 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3567 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3568 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3569 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3570 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3571 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3572 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3573 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3574 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3575 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3576 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3577 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3578 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3579 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3580 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3581 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3582 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3583 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3584 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3585 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3586 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 3587 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3588 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3589 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3590 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3591 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3592 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3593 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3594 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3595 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3596 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3597 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3598 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3599 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3600 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3601 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3602 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3603 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3604 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3605 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3606 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3607 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3608 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3609 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3610 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3611 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3612 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3613 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3614 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3615 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3616 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3617 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3618 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3619 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3620 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3621 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3622 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3623 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3624 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3625 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3626 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3627 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3628 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3629 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
3630 /* default Intel */
3631 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
3632 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3633 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3634 {}
3635};
3636
16ded525 3637/*
df694daa 3638 * ALC880 codec presets
16ded525 3639 */
16ded525
TI
3640static struct alc_config_preset alc880_presets[] = {
3641 [ALC880_3ST] = {
e9edcee0 3642 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3643 .init_verbs = { alc880_volume_init_verbs,
3644 alc880_pin_3stack_init_verbs },
16ded525 3645 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3646 .dac_nids = alc880_dac_nids,
16ded525
TI
3647 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3648 .channel_mode = alc880_threestack_modes,
4e195a7b 3649 .need_dac_fix = 1,
16ded525
TI
3650 .input_mux = &alc880_capture_source,
3651 },
3652 [ALC880_3ST_DIG] = {
e9edcee0 3653 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3654 .init_verbs = { alc880_volume_init_verbs,
3655 alc880_pin_3stack_init_verbs },
16ded525 3656 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3657 .dac_nids = alc880_dac_nids,
3658 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3659 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3660 .channel_mode = alc880_threestack_modes,
4e195a7b 3661 .need_dac_fix = 1,
16ded525
TI
3662 .input_mux = &alc880_capture_source,
3663 },
df694daa
KY
3664 [ALC880_TCL_S700] = {
3665 .mixers = { alc880_tcl_s700_mixer },
3666 .init_verbs = { alc880_volume_init_verbs,
3667 alc880_pin_tcl_S700_init_verbs,
3668 alc880_gpio2_init_verbs },
3669 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3670 .dac_nids = alc880_dac_nids,
f9e336f6
TI
3671 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3672 .num_adc_nids = 1, /* single ADC */
df694daa
KY
3673 .hp_nid = 0x03,
3674 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3675 .channel_mode = alc880_2_jack_modes,
3676 .input_mux = &alc880_capture_source,
3677 },
16ded525 3678 [ALC880_5ST] = {
f12ab1e0
TI
3679 .mixers = { alc880_three_stack_mixer,
3680 alc880_five_stack_mixer},
3681 .init_verbs = { alc880_volume_init_verbs,
3682 alc880_pin_5stack_init_verbs },
16ded525
TI
3683 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3684 .dac_nids = alc880_dac_nids,
16ded525
TI
3685 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3686 .channel_mode = alc880_fivestack_modes,
3687 .input_mux = &alc880_capture_source,
3688 },
3689 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3690 .mixers = { alc880_three_stack_mixer,
3691 alc880_five_stack_mixer },
3692 .init_verbs = { alc880_volume_init_verbs,
3693 alc880_pin_5stack_init_verbs },
16ded525
TI
3694 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3695 .dac_nids = alc880_dac_nids,
3696 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3697 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3698 .channel_mode = alc880_fivestack_modes,
3699 .input_mux = &alc880_capture_source,
3700 },
b6482d48
TI
3701 [ALC880_6ST] = {
3702 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3703 .init_verbs = { alc880_volume_init_verbs,
3704 alc880_pin_6stack_init_verbs },
b6482d48
TI
3705 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3706 .dac_nids = alc880_6st_dac_nids,
3707 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3708 .channel_mode = alc880_sixstack_modes,
3709 .input_mux = &alc880_6stack_capture_source,
3710 },
16ded525 3711 [ALC880_6ST_DIG] = {
e9edcee0 3712 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3713 .init_verbs = { alc880_volume_init_verbs,
3714 alc880_pin_6stack_init_verbs },
16ded525
TI
3715 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3716 .dac_nids = alc880_6st_dac_nids,
3717 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3718 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3719 .channel_mode = alc880_sixstack_modes,
3720 .input_mux = &alc880_6stack_capture_source,
3721 },
3722 [ALC880_W810] = {
e9edcee0 3723 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3724 .init_verbs = { alc880_volume_init_verbs,
3725 alc880_pin_w810_init_verbs,
b0af0de5 3726 alc880_gpio2_init_verbs },
16ded525
TI
3727 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3728 .dac_nids = alc880_w810_dac_nids,
3729 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3730 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3731 .channel_mode = alc880_w810_modes,
3732 .input_mux = &alc880_capture_source,
3733 },
3734 [ALC880_Z71V] = {
e9edcee0 3735 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3736 .init_verbs = { alc880_volume_init_verbs,
3737 alc880_pin_z71v_init_verbs },
16ded525
TI
3738 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3739 .dac_nids = alc880_z71v_dac_nids,
3740 .dig_out_nid = ALC880_DIGOUT_NID,
3741 .hp_nid = 0x03,
e9edcee0
TI
3742 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3743 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3744 .input_mux = &alc880_capture_source,
3745 },
3746 [ALC880_F1734] = {
e9edcee0 3747 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3748 .init_verbs = { alc880_volume_init_verbs,
3749 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3750 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3751 .dac_nids = alc880_f1734_dac_nids,
3752 .hp_nid = 0x02,
3753 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3754 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3755 .input_mux = &alc880_f1734_capture_source,
3756 .unsol_event = alc880_uniwill_p53_unsol_event,
3757 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3758 },
3759 [ALC880_ASUS] = {
e9edcee0 3760 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3761 .init_verbs = { alc880_volume_init_verbs,
3762 alc880_pin_asus_init_verbs,
e9edcee0
TI
3763 alc880_gpio1_init_verbs },
3764 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3765 .dac_nids = alc880_asus_dac_nids,
3766 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3767 .channel_mode = alc880_asus_modes,
4e195a7b 3768 .need_dac_fix = 1,
16ded525
TI
3769 .input_mux = &alc880_capture_source,
3770 },
3771 [ALC880_ASUS_DIG] = {
e9edcee0 3772 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3773 .init_verbs = { alc880_volume_init_verbs,
3774 alc880_pin_asus_init_verbs,
e9edcee0
TI
3775 alc880_gpio1_init_verbs },
3776 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3777 .dac_nids = alc880_asus_dac_nids,
16ded525 3778 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3779 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3780 .channel_mode = alc880_asus_modes,
4e195a7b 3781 .need_dac_fix = 1,
16ded525
TI
3782 .input_mux = &alc880_capture_source,
3783 },
df694daa
KY
3784 [ALC880_ASUS_DIG2] = {
3785 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3786 .init_verbs = { alc880_volume_init_verbs,
3787 alc880_pin_asus_init_verbs,
df694daa
KY
3788 alc880_gpio2_init_verbs }, /* use GPIO2 */
3789 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3790 .dac_nids = alc880_asus_dac_nids,
3791 .dig_out_nid = ALC880_DIGOUT_NID,
3792 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3793 .channel_mode = alc880_asus_modes,
4e195a7b 3794 .need_dac_fix = 1,
df694daa
KY
3795 .input_mux = &alc880_capture_source,
3796 },
16ded525 3797 [ALC880_ASUS_W1V] = {
e9edcee0 3798 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3799 .init_verbs = { alc880_volume_init_verbs,
3800 alc880_pin_asus_init_verbs,
e9edcee0
TI
3801 alc880_gpio1_init_verbs },
3802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3803 .dac_nids = alc880_asus_dac_nids,
16ded525 3804 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3805 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3806 .channel_mode = alc880_asus_modes,
4e195a7b 3807 .need_dac_fix = 1,
16ded525
TI
3808 .input_mux = &alc880_capture_source,
3809 },
3810 [ALC880_UNIWILL_DIG] = {
45bdd1c1 3811 .mixers = { alc880_asus_mixer },
ccc656ce
KY
3812 .init_verbs = { alc880_volume_init_verbs,
3813 alc880_pin_asus_init_verbs },
e9edcee0
TI
3814 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3815 .dac_nids = alc880_asus_dac_nids,
16ded525 3816 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3817 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3818 .channel_mode = alc880_asus_modes,
4e195a7b 3819 .need_dac_fix = 1,
16ded525
TI
3820 .input_mux = &alc880_capture_source,
3821 },
ccc656ce
KY
3822 [ALC880_UNIWILL] = {
3823 .mixers = { alc880_uniwill_mixer },
3824 .init_verbs = { alc880_volume_init_verbs,
3825 alc880_uniwill_init_verbs },
3826 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3827 .dac_nids = alc880_asus_dac_nids,
3828 .dig_out_nid = ALC880_DIGOUT_NID,
3829 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3830 .channel_mode = alc880_threestack_modes,
3831 .need_dac_fix = 1,
3832 .input_mux = &alc880_capture_source,
3833 .unsol_event = alc880_uniwill_unsol_event,
3834 .init_hook = alc880_uniwill_automute,
3835 },
3836 [ALC880_UNIWILL_P53] = {
3837 .mixers = { alc880_uniwill_p53_mixer },
3838 .init_verbs = { alc880_volume_init_verbs,
3839 alc880_uniwill_p53_init_verbs },
3840 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3841 .dac_nids = alc880_asus_dac_nids,
3842 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3843 .channel_mode = alc880_threestack_modes,
3844 .input_mux = &alc880_capture_source,
3845 .unsol_event = alc880_uniwill_p53_unsol_event,
3846 .init_hook = alc880_uniwill_p53_hp_automute,
3847 },
3848 [ALC880_FUJITSU] = {
45bdd1c1 3849 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
3850 .init_verbs = { alc880_volume_init_verbs,
3851 alc880_uniwill_p53_init_verbs,
3852 alc880_beep_init_verbs },
3853 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3854 .dac_nids = alc880_dac_nids,
d53d7d9e 3855 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3856 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3857 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3858 .input_mux = &alc880_capture_source,
3859 .unsol_event = alc880_uniwill_p53_unsol_event,
3860 .init_hook = alc880_uniwill_p53_hp_automute,
3861 },
df694daa
KY
3862 [ALC880_CLEVO] = {
3863 .mixers = { alc880_three_stack_mixer },
3864 .init_verbs = { alc880_volume_init_verbs,
3865 alc880_pin_clevo_init_verbs },
3866 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3867 .dac_nids = alc880_dac_nids,
3868 .hp_nid = 0x03,
3869 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3870 .channel_mode = alc880_threestack_modes,
4e195a7b 3871 .need_dac_fix = 1,
df694daa
KY
3872 .input_mux = &alc880_capture_source,
3873 },
ae6b813a
TI
3874 [ALC880_LG] = {
3875 .mixers = { alc880_lg_mixer },
3876 .init_verbs = { alc880_volume_init_verbs,
3877 alc880_lg_init_verbs },
3878 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3879 .dac_nids = alc880_lg_dac_nids,
3880 .dig_out_nid = ALC880_DIGOUT_NID,
3881 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3882 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3883 .need_dac_fix = 1,
ae6b813a
TI
3884 .input_mux = &alc880_lg_capture_source,
3885 .unsol_event = alc880_lg_unsol_event,
3886 .init_hook = alc880_lg_automute,
cb53c626
TI
3887#ifdef CONFIG_SND_HDA_POWER_SAVE
3888 .loopbacks = alc880_lg_loopbacks,
3889#endif
ae6b813a 3890 },
d681518a
TI
3891 [ALC880_LG_LW] = {
3892 .mixers = { alc880_lg_lw_mixer },
3893 .init_verbs = { alc880_volume_init_verbs,
3894 alc880_lg_lw_init_verbs },
0a8c5da3 3895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3896 .dac_nids = alc880_dac_nids,
3897 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3898 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3899 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3900 .input_mux = &alc880_lg_lw_capture_source,
3901 .unsol_event = alc880_lg_lw_unsol_event,
3902 .init_hook = alc880_lg_lw_automute,
3903 },
df99cd33
TI
3904 [ALC880_MEDION_RIM] = {
3905 .mixers = { alc880_medion_rim_mixer },
3906 .init_verbs = { alc880_volume_init_verbs,
3907 alc880_medion_rim_init_verbs,
3908 alc_gpio2_init_verbs },
3909 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3910 .dac_nids = alc880_dac_nids,
3911 .dig_out_nid = ALC880_DIGOUT_NID,
3912 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3913 .channel_mode = alc880_2_jack_modes,
3914 .input_mux = &alc880_medion_rim_capture_source,
3915 .unsol_event = alc880_medion_rim_unsol_event,
3916 .init_hook = alc880_medion_rim_automute,
3917 },
16ded525
TI
3918#ifdef CONFIG_SND_DEBUG
3919 [ALC880_TEST] = {
e9edcee0
TI
3920 .mixers = { alc880_test_mixer },
3921 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3922 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3923 .dac_nids = alc880_test_dac_nids,
3924 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3925 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3926 .channel_mode = alc880_test_modes,
3927 .input_mux = &alc880_test_capture_source,
3928 },
3929#endif
3930};
3931
e9edcee0
TI
3932/*
3933 * Automatic parse of I/O pins from the BIOS configuration
3934 */
3935
e9edcee0
TI
3936enum {
3937 ALC_CTL_WIDGET_VOL,
3938 ALC_CTL_WIDGET_MUTE,
3939 ALC_CTL_BIND_MUTE,
3940};
c8b6bf9b 3941static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3942 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3943 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3944 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3945};
3946
3947/* add dynamic controls */
f12ab1e0
TI
3948static int add_control(struct alc_spec *spec, int type, const char *name,
3949 unsigned long val)
e9edcee0 3950{
c8b6bf9b 3951 struct snd_kcontrol_new *knew;
e9edcee0 3952
603c4019
TI
3953 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3954 knew = snd_array_new(&spec->kctls);
3955 if (!knew)
3956 return -ENOMEM;
e9edcee0 3957 *knew = alc880_control_templates[type];
543537bd 3958 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3959 if (!knew->name)
e9edcee0
TI
3960 return -ENOMEM;
3961 knew->private_value = val;
e9edcee0
TI
3962 return 0;
3963}
3964
3965#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3966#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3967#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3968#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3969#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3970#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3971#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3972#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3973#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3974#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3975#define ALC880_PIN_CD_NID 0x1c
3976
3977/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3978static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3979 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3980{
3981 hda_nid_t nid;
3982 int assigned[4];
3983 int i, j;
3984
3985 memset(assigned, 0, sizeof(assigned));
b0af0de5 3986 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3987
3988 /* check the pins hardwired to audio widget */
3989 for (i = 0; i < cfg->line_outs; i++) {
3990 nid = cfg->line_out_pins[i];
3991 if (alc880_is_fixed_pin(nid)) {
3992 int idx = alc880_fixed_pin_idx(nid);
5014f193 3993 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3994 assigned[idx] = 1;
3995 }
3996 }
3997 /* left pins can be connect to any audio widget */
3998 for (i = 0; i < cfg->line_outs; i++) {
3999 nid = cfg->line_out_pins[i];
4000 if (alc880_is_fixed_pin(nid))
4001 continue;
4002 /* search for an empty channel */
4003 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4004 if (!assigned[j]) {
4005 spec->multiout.dac_nids[i] =
4006 alc880_idx_to_dac(j);
e9edcee0
TI
4007 assigned[j] = 1;
4008 break;
4009 }
4010 }
4011 }
4012 spec->multiout.num_dacs = cfg->line_outs;
4013 return 0;
4014}
4015
4016/* add playback controls from the parsed DAC table */
df694daa
KY
4017static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4018 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4019{
4020 char name[32];
f12ab1e0
TI
4021 static const char *chname[4] = {
4022 "Front", "Surround", NULL /*CLFE*/, "Side"
4023 };
e9edcee0
TI
4024 hda_nid_t nid;
4025 int i, err;
4026
4027 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4028 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4029 continue;
4030 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4031 if (i == 2) {
4032 /* Center/LFE */
f12ab1e0
TI
4033 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4034 "Center Playback Volume",
4035 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4036 HDA_OUTPUT));
4037 if (err < 0)
e9edcee0 4038 return err;
f12ab1e0
TI
4039 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4040 "LFE Playback Volume",
4041 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4042 HDA_OUTPUT));
4043 if (err < 0)
e9edcee0 4044 return err;
f12ab1e0
TI
4045 err = add_control(spec, ALC_CTL_BIND_MUTE,
4046 "Center Playback Switch",
4047 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4048 HDA_INPUT));
4049 if (err < 0)
e9edcee0 4050 return err;
f12ab1e0
TI
4051 err = add_control(spec, ALC_CTL_BIND_MUTE,
4052 "LFE Playback Switch",
4053 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4054 HDA_INPUT));
4055 if (err < 0)
e9edcee0
TI
4056 return err;
4057 } else {
4058 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
4059 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4060 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4061 HDA_OUTPUT));
4062 if (err < 0)
e9edcee0
TI
4063 return err;
4064 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
4065 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4066 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4067 HDA_INPUT));
4068 if (err < 0)
e9edcee0
TI
4069 return err;
4070 }
4071 }
e9edcee0
TI
4072 return 0;
4073}
4074
8d88bc3d
TI
4075/* add playback controls for speaker and HP outputs */
4076static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4077 const char *pfx)
e9edcee0
TI
4078{
4079 hda_nid_t nid;
4080 int err;
8d88bc3d 4081 char name[32];
e9edcee0 4082
f12ab1e0 4083 if (!pin)
e9edcee0
TI
4084 return 0;
4085
4086 if (alc880_is_fixed_pin(pin)) {
4087 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4088 /* specify the DAC as the extra output */
f12ab1e0 4089 if (!spec->multiout.hp_nid)
e9edcee0 4090 spec->multiout.hp_nid = nid;
82bc955f
TI
4091 else
4092 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4093 /* control HP volume/switch on the output mixer amp */
4094 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 4095 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4096 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4097 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4098 if (err < 0)
e9edcee0 4099 return err;
8d88bc3d 4100 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4101 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4102 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4103 if (err < 0)
e9edcee0
TI
4104 return err;
4105 } else if (alc880_is_multi_pin(pin)) {
4106 /* set manual connection */
e9edcee0 4107 /* we have only a switch on HP-out PIN */
8d88bc3d 4108 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4109 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4110 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4111 if (err < 0)
e9edcee0
TI
4112 return err;
4113 }
4114 return 0;
4115}
4116
4117/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4118static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4119 const char *ctlname,
df694daa 4120 int idx, hda_nid_t mix_nid)
e9edcee0
TI
4121{
4122 char name[32];
df694daa 4123 int err;
e9edcee0
TI
4124
4125 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
4126 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4127 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4128 if (err < 0)
e9edcee0
TI
4129 return err;
4130 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
4131 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4132 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4133 if (err < 0)
e9edcee0
TI
4134 return err;
4135 return 0;
4136}
4137
4138/* create playback/capture controls for input pins */
df694daa
KY
4139static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4140 const struct auto_pin_cfg *cfg)
e9edcee0 4141{
61b9b9b1 4142 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4143 int i, err, idx;
e9edcee0
TI
4144
4145 for (i = 0; i < AUTO_PIN_LAST; i++) {
4146 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 4147 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
4148 err = new_analog_input(spec, cfg->input_pins[i],
4149 auto_pin_cfg_labels[i],
df694daa 4150 idx, 0x0b);
e9edcee0
TI
4151 if (err < 0)
4152 return err;
f12ab1e0
TI
4153 imux->items[imux->num_items].label =
4154 auto_pin_cfg_labels[i];
4155 imux->items[imux->num_items].index =
4156 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
4157 imux->num_items++;
4158 }
4159 }
4160 return 0;
4161}
4162
f6c7e546
TI
4163static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4164 unsigned int pin_type)
4165{
4166 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4167 pin_type);
4168 /* unmute pin */
d260cdf6
TI
4169 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4170 AMP_OUT_UNMUTE);
f6c7e546
TI
4171}
4172
df694daa
KY
4173static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4174 hda_nid_t nid, int pin_type,
e9edcee0
TI
4175 int dac_idx)
4176{
f6c7e546 4177 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4178 /* need the manual connection? */
4179 if (alc880_is_multi_pin(nid)) {
4180 struct alc_spec *spec = codec->spec;
4181 int idx = alc880_multi_pin_idx(nid);
4182 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4183 AC_VERB_SET_CONNECT_SEL,
4184 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4185 }
4186}
4187
baba8ee9
TI
4188static int get_pin_type(int line_out_type)
4189{
4190 if (line_out_type == AUTO_PIN_HP_OUT)
4191 return PIN_HP;
4192 else
4193 return PIN_OUT;
4194}
4195
e9edcee0
TI
4196static void alc880_auto_init_multi_out(struct hda_codec *codec)
4197{
4198 struct alc_spec *spec = codec->spec;
4199 int i;
ea1fb29a 4200
bc9f98a9 4201 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
4202 for (i = 0; i < spec->autocfg.line_outs; i++) {
4203 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4204 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4205 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4206 }
4207}
4208
8d88bc3d 4209static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4210{
4211 struct alc_spec *spec = codec->spec;
4212 hda_nid_t pin;
4213
82bc955f 4214 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4215 if (pin) /* connect to front */
4216 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4217 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4218 if (pin) /* connect to front */
4219 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4220}
4221
4222static void alc880_auto_init_analog_input(struct hda_codec *codec)
4223{
4224 struct alc_spec *spec = codec->spec;
4225 int i;
4226
4227 for (i = 0; i < AUTO_PIN_LAST; i++) {
4228 hda_nid_t nid = spec->autocfg.input_pins[i];
4229 if (alc880_is_input_pin(nid)) {
23f0c048 4230 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4231 if (nid != ALC880_PIN_CD_NID &&
4232 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4233 snd_hda_codec_write(codec, nid, 0,
4234 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4235 AMP_OUT_MUTE);
4236 }
4237 }
4238}
4239
4240/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4241/* return 1 if successful, 0 if the proper config is not found,
4242 * or a negative error code
4243 */
e9edcee0
TI
4244static int alc880_parse_auto_config(struct hda_codec *codec)
4245{
4246 struct alc_spec *spec = codec->spec;
6a05ac4a 4247 int i, err;
df694daa 4248 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4249
f12ab1e0
TI
4250 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4251 alc880_ignore);
4252 if (err < 0)
e9edcee0 4253 return err;
f12ab1e0 4254 if (!spec->autocfg.line_outs)
e9edcee0 4255 return 0; /* can't find valid BIOS pin config */
df694daa 4256
f12ab1e0
TI
4257 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4258 if (err < 0)
4259 return err;
4260 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4261 if (err < 0)
4262 return err;
4263 err = alc880_auto_create_extra_out(spec,
4264 spec->autocfg.speaker_pins[0],
4265 "Speaker");
4266 if (err < 0)
4267 return err;
4268 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4269 "Headphone");
4270 if (err < 0)
4271 return err;
4272 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4273 if (err < 0)
e9edcee0
TI
4274 return err;
4275
4276 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4277
6a05ac4a
TI
4278 /* check multiple SPDIF-out (for recent codecs) */
4279 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4280 hda_nid_t dig_nid;
4281 err = snd_hda_get_connections(codec,
4282 spec->autocfg.dig_out_pins[i],
4283 &dig_nid, 1);
4284 if (err < 0)
4285 continue;
4286 if (!i)
4287 spec->multiout.dig_out_nid = dig_nid;
4288 else {
4289 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4290 spec->slave_dig_outs[i - 1] = dig_nid;
4291 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4292 break;
4293 }
4294 }
e9edcee0
TI
4295 if (spec->autocfg.dig_in_pin)
4296 spec->dig_in_nid = ALC880_DIGIN_NID;
4297
603c4019 4298 if (spec->kctls.list)
d88897ea 4299 add_mixer(spec, spec->kctls.list);
e9edcee0 4300
d88897ea 4301 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4302
a1e8d2da 4303 spec->num_mux_defs = 1;
61b9b9b1 4304 spec->input_mux = &spec->private_imux[0];
e9edcee0
TI
4305
4306 return 1;
4307}
4308
ae6b813a
TI
4309/* additional initialization for auto-configuration model */
4310static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4311{
f6c7e546 4312 struct alc_spec *spec = codec->spec;
e9edcee0 4313 alc880_auto_init_multi_out(codec);
8d88bc3d 4314 alc880_auto_init_extra_out(codec);
e9edcee0 4315 alc880_auto_init_analog_input(codec);
f6c7e546 4316 if (spec->unsol_event)
7fb0d78f 4317 alc_inithook(codec);
e9edcee0
TI
4318}
4319
f9e336f6
TI
4320static void set_capture_mixer(struct alc_spec *spec)
4321{
a23b688f
TI
4322 static struct snd_kcontrol_new *caps[2][3] = {
4323 { alc_capture_mixer_nosrc1,
4324 alc_capture_mixer_nosrc2,
4325 alc_capture_mixer_nosrc3 },
4326 { alc_capture_mixer1,
4327 alc_capture_mixer2,
4328 alc_capture_mixer3 },
f9e336f6 4329 };
a23b688f
TI
4330 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4331 int mux;
4332 if (spec->input_mux && spec->input_mux->num_items > 1)
4333 mux = 1;
4334 else
4335 mux = 0;
4336 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4337 }
f9e336f6
TI
4338}
4339
45bdd1c1
TI
4340#define set_beep_amp(spec, nid, idx, dir) \
4341 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4342
4343/*
4344 * OK, here we have finally the patch for ALC880
4345 */
4346
1da177e4
LT
4347static int patch_alc880(struct hda_codec *codec)
4348{
4349 struct alc_spec *spec;
4350 int board_config;
df694daa 4351 int err;
1da177e4 4352
e560d8d8 4353 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4354 if (spec == NULL)
4355 return -ENOMEM;
4356
4357 codec->spec = spec;
4358
f5fcc13c
TI
4359 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4360 alc880_models,
4361 alc880_cfg_tbl);
4362 if (board_config < 0) {
9c7f852e
TI
4363 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4364 "trying auto-probe from BIOS...\n");
e9edcee0 4365 board_config = ALC880_AUTO;
1da177e4 4366 }
1da177e4 4367
e9edcee0
TI
4368 if (board_config == ALC880_AUTO) {
4369 /* automatic parse from the BIOS config */
4370 err = alc880_parse_auto_config(codec);
4371 if (err < 0) {
4372 alc_free(codec);
4373 return err;
f12ab1e0 4374 } else if (!err) {
9c7f852e
TI
4375 printk(KERN_INFO
4376 "hda_codec: Cannot set up configuration "
4377 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
4378 board_config = ALC880_3ST;
4379 }
1da177e4
LT
4380 }
4381
680cd536
KK
4382 err = snd_hda_attach_beep_device(codec, 0x1);
4383 if (err < 0) {
4384 alc_free(codec);
4385 return err;
4386 }
4387
df694daa
KY
4388 if (board_config != ALC880_AUTO)
4389 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
4390
4391 spec->stream_name_analog = "ALC880 Analog";
4392 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4393 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 4394 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
4395
4396 spec->stream_name_digital = "ALC880 Digital";
4397 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4398 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4399
f12ab1e0 4400 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 4401 /* check whether NID 0x07 is valid */
54d17403 4402 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
4403 /* get type */
4404 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
4405 if (wcap != AC_WID_AUD_IN) {
4406 spec->adc_nids = alc880_adc_nids_alt;
4407 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
4408 } else {
4409 spec->adc_nids = alc880_adc_nids;
4410 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
4411 }
4412 }
f9e336f6 4413 set_capture_mixer(spec);
45bdd1c1 4414 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 4415
2134ea4f
TI
4416 spec->vmaster_nid = 0x0c;
4417
1da177e4 4418 codec->patch_ops = alc_patch_ops;
e9edcee0 4419 if (board_config == ALC880_AUTO)
ae6b813a 4420 spec->init_hook = alc880_auto_init;
cb53c626
TI
4421#ifdef CONFIG_SND_HDA_POWER_SAVE
4422 if (!spec->loopback.amplist)
4423 spec->loopback.amplist = alc880_loopbacks;
4424#endif
daead538 4425 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
4426
4427 return 0;
4428}
4429
e9edcee0 4430
1da177e4
LT
4431/*
4432 * ALC260 support
4433 */
4434
e9edcee0
TI
4435static hda_nid_t alc260_dac_nids[1] = {
4436 /* front */
4437 0x02,
4438};
4439
4440static hda_nid_t alc260_adc_nids[1] = {
4441 /* ADC0 */
4442 0x04,
4443};
4444
df694daa 4445static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4446 /* ADC1 */
4447 0x05,
4448};
4449
d57fdac0
JW
4450/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4451 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4452 */
4453static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4454 /* ADC0, ADC1 */
4455 0x04, 0x05
4456};
4457
e9edcee0
TI
4458#define ALC260_DIGOUT_NID 0x03
4459#define ALC260_DIGIN_NID 0x06
4460
4461static struct hda_input_mux alc260_capture_source = {
4462 .num_items = 4,
4463 .items = {
4464 { "Mic", 0x0 },
4465 { "Front Mic", 0x1 },
4466 { "Line", 0x2 },
4467 { "CD", 0x4 },
4468 },
4469};
4470
17e7aec6 4471/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4472 * headphone jack and the internal CD lines since these are the only pins at
4473 * which audio can appear. For flexibility, also allow the option of
4474 * recording the mixer output on the second ADC (ADC0 doesn't have a
4475 * connection to the mixer output).
a9430dd8 4476 */
a1e8d2da
JW
4477static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4478 {
4479 .num_items = 3,
4480 .items = {
4481 { "Mic/Line", 0x0 },
4482 { "CD", 0x4 },
4483 { "Headphone", 0x2 },
4484 },
a9430dd8 4485 },
a1e8d2da
JW
4486 {
4487 .num_items = 4,
4488 .items = {
4489 { "Mic/Line", 0x0 },
4490 { "CD", 0x4 },
4491 { "Headphone", 0x2 },
4492 { "Mixer", 0x5 },
4493 },
4494 },
4495
a9430dd8
JW
4496};
4497
a1e8d2da
JW
4498/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4499 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4500 */
a1e8d2da
JW
4501static struct hda_input_mux alc260_acer_capture_sources[2] = {
4502 {
4503 .num_items = 4,
4504 .items = {
4505 { "Mic", 0x0 },
4506 { "Line", 0x2 },
4507 { "CD", 0x4 },
4508 { "Headphone", 0x5 },
4509 },
4510 },
4511 {
4512 .num_items = 5,
4513 .items = {
4514 { "Mic", 0x0 },
4515 { "Line", 0x2 },
4516 { "CD", 0x4 },
4517 { "Headphone", 0x6 },
4518 { "Mixer", 0x5 },
4519 },
0bfc90e9
JW
4520 },
4521};
cc959489
MS
4522
4523/* Maxdata Favorit 100XS */
4524static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4525 {
4526 .num_items = 2,
4527 .items = {
4528 { "Line/Mic", 0x0 },
4529 { "CD", 0x4 },
4530 },
4531 },
4532 {
4533 .num_items = 3,
4534 .items = {
4535 { "Line/Mic", 0x0 },
4536 { "CD", 0x4 },
4537 { "Mixer", 0x5 },
4538 },
4539 },
4540};
4541
1da177e4
LT
4542/*
4543 * This is just place-holder, so there's something for alc_build_pcms to look
4544 * at when it calculates the maximum number of channels. ALC260 has no mixer
4545 * element which allows changing the channel mode, so the verb list is
4546 * never used.
4547 */
d2a6d7dc 4548static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4549 { 2, NULL },
4550};
4551
df694daa
KY
4552
4553/* Mixer combinations
4554 *
4555 * basic: base_output + input + pc_beep + capture
4556 * HP: base_output + input + capture_alt
4557 * HP_3013: hp_3013 + input + capture
4558 * fujitsu: fujitsu + capture
0bfc90e9 4559 * acer: acer + capture
df694daa
KY
4560 */
4561
4562static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4563 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4564 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4566 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4567 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4568 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4569 { } /* end */
f12ab1e0 4570};
1da177e4 4571
df694daa 4572static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4573 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4574 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4575 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4576 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4578 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4581 { } /* end */
4582};
4583
bec15c3a
TI
4584/* update HP, line and mono out pins according to the master switch */
4585static void alc260_hp_master_update(struct hda_codec *codec,
4586 hda_nid_t hp, hda_nid_t line,
4587 hda_nid_t mono)
4588{
4589 struct alc_spec *spec = codec->spec;
4590 unsigned int val = spec->master_sw ? PIN_HP : 0;
4591 /* change HP and line-out pins */
30cde0aa 4592 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 4593 val);
30cde0aa 4594 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4595 val);
4596 /* mono (speaker) depending on the HP jack sense */
4597 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 4598 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4599 val);
4600}
4601
4602static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4603 struct snd_ctl_elem_value *ucontrol)
4604{
4605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4606 struct alc_spec *spec = codec->spec;
4607 *ucontrol->value.integer.value = spec->master_sw;
4608 return 0;
4609}
4610
4611static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4612 struct snd_ctl_elem_value *ucontrol)
4613{
4614 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4615 struct alc_spec *spec = codec->spec;
4616 int val = !!*ucontrol->value.integer.value;
4617 hda_nid_t hp, line, mono;
4618
4619 if (val == spec->master_sw)
4620 return 0;
4621 spec->master_sw = val;
4622 hp = (kcontrol->private_value >> 16) & 0xff;
4623 line = (kcontrol->private_value >> 8) & 0xff;
4624 mono = kcontrol->private_value & 0xff;
4625 alc260_hp_master_update(codec, hp, line, mono);
4626 return 1;
4627}
4628
4629static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4630 {
4631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4632 .name = "Master Playback Switch",
4633 .info = snd_ctl_boolean_mono_info,
4634 .get = alc260_hp_master_sw_get,
4635 .put = alc260_hp_master_sw_put,
4636 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4637 },
4638 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4639 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4640 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4641 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4642 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4643 HDA_OUTPUT),
4644 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4645 { } /* end */
4646};
4647
4648static struct hda_verb alc260_hp_unsol_verbs[] = {
4649 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4650 {},
4651};
4652
4653static void alc260_hp_automute(struct hda_codec *codec)
4654{
4655 struct alc_spec *spec = codec->spec;
4656 unsigned int present;
4657
4658 present = snd_hda_codec_read(codec, 0x10, 0,
4659 AC_VERB_GET_PIN_SENSE, 0);
4660 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4661 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4662}
4663
4664static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4665{
4666 if ((res >> 26) == ALC880_HP_EVENT)
4667 alc260_hp_automute(codec);
4668}
4669
df694daa 4670static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4671 {
4672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4673 .name = "Master Playback Switch",
4674 .info = snd_ctl_boolean_mono_info,
4675 .get = alc260_hp_master_sw_get,
4676 .put = alc260_hp_master_sw_put,
30cde0aa 4677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 4678 },
df694daa
KY
4679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4687 { } /* end */
4688};
4689
3f878308
KY
4690static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4691 .ops = &snd_hda_bind_vol,
4692 .values = {
4693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4696 0
4697 },
4698};
4699
4700static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4701 .ops = &snd_hda_bind_sw,
4702 .values = {
4703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4705 0
4706 },
4707};
4708
4709static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4714 { } /* end */
4715};
4716
bec15c3a
TI
4717static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4719 {},
4720};
4721
4722static void alc260_hp_3013_automute(struct hda_codec *codec)
4723{
4724 struct alc_spec *spec = codec->spec;
4725 unsigned int present;
4726
4727 present = snd_hda_codec_read(codec, 0x15, 0,
4728 AC_VERB_GET_PIN_SENSE, 0);
4729 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
30cde0aa 4730 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
4731}
4732
4733static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4734 unsigned int res)
4735{
4736 if ((res >> 26) == ALC880_HP_EVENT)
4737 alc260_hp_3013_automute(codec);
4738}
4739
3f878308
KY
4740static void alc260_hp_3012_automute(struct hda_codec *codec)
4741{
4742 unsigned int present, bits;
4743
4744 present = snd_hda_codec_read(codec, 0x10, 0,
4745 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4746
4747 bits = present ? 0 : PIN_OUT;
4748 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4749 bits);
4750 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4751 bits);
4752 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4753 bits);
4754}
4755
4756static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4757 unsigned int res)
4758{
4759 if ((res >> 26) == ALC880_HP_EVENT)
4760 alc260_hp_3012_automute(codec);
4761}
4762
4763/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4764 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4765 */
c8b6bf9b 4766static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4768 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4769 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4770 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4771 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4772 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4773 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4774 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
4775 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4776 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4777 { } /* end */
4778};
4779
a1e8d2da
JW
4780/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4781 * versions of the ALC260 don't act on requests to enable mic bias from NID
4782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4783 * datasheet doesn't mention this restriction. At this stage it's not clear
4784 * whether this behaviour is intentional or is a hardware bug in chip
4785 * revisions available in early 2006. Therefore for now allow the
4786 * "Headphone Jack Mode" control to span all choices, but if it turns out
4787 * that the lack of mic bias for this NID is intentional we could change the
4788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4789 *
4790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4791 * don't appear to make the mic bias available from the "line" jack, even
4792 * though the NID used for this jack (0x14) can supply it. The theory is
4793 * that perhaps Acer have included blocking capacitors between the ALC260
4794 * and the output jack. If this turns out to be the case for all such
4795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4796 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4797 *
4798 * The C20x Tablet series have a mono internal speaker which is controlled
4799 * via the chip's Mono sum widget and pin complex, so include the necessary
4800 * controls for such models. On models without a "mono speaker" the control
4801 * won't do anything.
a1e8d2da 4802 */
0bfc90e9
JW
4803static struct snd_kcontrol_new alc260_acer_mixer[] = {
4804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4807 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4808 HDA_OUTPUT),
31bffaa9 4809 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4810 HDA_INPUT),
0bfc90e9
JW
4811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
4819 { } /* end */
4820};
4821
cc959489
MS
4822/* Maxdata Favorit 100XS: one output and one input (0x12) jack
4823 */
4824static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4825 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4826 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4827 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4828 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4829 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4830 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4831 { } /* end */
4832};
4833
bc9f98a9
KY
4834/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4835 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4836 */
4837static struct snd_kcontrol_new alc260_will_mixer[] = {
4838 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4839 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4841 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4842 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4843 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4844 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4845 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4846 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4847 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
4848 { } /* end */
4849};
4850
4851/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4852 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4853 */
4854static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4855 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4856 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4858 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4859 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4860 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4861 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4862 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4863 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4864 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4865 { } /* end */
4866};
4867
df694daa
KY
4868/*
4869 * initialization verbs
4870 */
1da177e4
LT
4871static struct hda_verb alc260_init_verbs[] = {
4872 /* Line In pin widget for input */
05acb863 4873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4874 /* CD pin widget for input */
05acb863 4875 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4876 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4878 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4879 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4880 /* LINE-2 is used for line-out in rear */
05acb863 4881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4882 /* select line-out */
fd56f2db 4883 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4884 /* LINE-OUT pin */
05acb863 4885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4886 /* enable HP */
05acb863 4887 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4888 /* enable Mono */
05acb863
TI
4889 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4890 /* mute capture amp left and right */
16ded525 4891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4892 /* set connection select to line in (default select for this ADC) */
4893 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4894 /* mute capture amp left and right */
4895 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4896 /* set connection select to line in (default select for this ADC) */
4897 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4898 /* set vol=0 Line-Out mixer amp left and right */
4899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4900 /* unmute pin widget amp left and right (no gain on this amp) */
4901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4902 /* set vol=0 HP mixer amp left and right */
4903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904 /* unmute pin widget amp left and right (no gain on this amp) */
4905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4906 /* set vol=0 Mono mixer amp left and right */
4907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4908 /* unmute pin widget amp left and right (no gain on this amp) */
4909 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4910 /* unmute LINE-2 out pin */
4911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4912 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4913 * Line In 2 = 0x03
4914 */
cb53c626
TI
4915 /* mute analog inputs */
4916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4921 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4922 /* mute Front out path */
4923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4925 /* mute Headphone out path */
4926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4928 /* mute Mono out path */
4929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4930 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4931 { }
4932};
4933
474167d6 4934#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4935static struct hda_verb alc260_hp_init_verbs[] = {
4936 /* Headphone and output */
4937 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4938 /* mono output */
4939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4940 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4942 /* Mic2 (front panel) pin widget for input and vref at 80% */
4943 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4944 /* Line In pin widget for input */
4945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4946 /* Line-2 pin widget for output */
4947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4948 /* CD pin widget for input */
4949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4950 /* unmute amp left and right */
4951 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4952 /* set connection select to line in (default select for this ADC) */
4953 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4954 /* unmute Line-Out mixer amp left and right (volume = 0) */
4955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4956 /* mute pin widget amp left and right (no gain on this amp) */
4957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4958 /* unmute HP mixer amp left and right (volume = 0) */
4959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4960 /* mute pin widget amp left and right (no gain on this amp) */
4961 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4962 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4963 * Line In 2 = 0x03
4964 */
cb53c626
TI
4965 /* mute analog inputs */
4966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4971 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4972 /* Unmute Front out path */
4973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4975 /* Unmute Headphone out path */
4976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4978 /* Unmute Mono out path */
4979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4980 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4981 { }
4982};
474167d6 4983#endif
df694daa
KY
4984
4985static struct hda_verb alc260_hp_3013_init_verbs[] = {
4986 /* Line out and output */
4987 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4988 /* mono output */
4989 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4990 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4992 /* Mic2 (front panel) pin widget for input and vref at 80% */
4993 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4994 /* Line In pin widget for input */
4995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4996 /* Headphone pin widget for output */
4997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4998 /* CD pin widget for input */
4999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5000 /* unmute amp left and right */
5001 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5002 /* set connection select to line in (default select for this ADC) */
5003 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5004 /* unmute Line-Out mixer amp left and right (volume = 0) */
5005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5006 /* mute pin widget amp left and right (no gain on this amp) */
5007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5008 /* unmute HP mixer amp left and right (volume = 0) */
5009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5010 /* mute pin widget amp left and right (no gain on this amp) */
5011 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5012 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5013 * Line In 2 = 0x03
5014 */
cb53c626
TI
5015 /* mute analog inputs */
5016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5021 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5022 /* Unmute Front out path */
5023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5025 /* Unmute Headphone out path */
5026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5028 /* Unmute Mono out path */
5029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5031 { }
5032};
5033
a9430dd8 5034/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5035 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5036 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5037 */
5038static struct hda_verb alc260_fujitsu_init_verbs[] = {
5039 /* Disable all GPIOs */
5040 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5041 /* Internal speaker is connected to headphone pin */
5042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5043 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5045 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5047 /* Ensure all other unused pins are disabled and muted. */
5048 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5050 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5051 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5053 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5056
5057 /* Disable digital (SPDIF) pins */
5058 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5059 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5060
ea1fb29a 5061 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5062 * when acting as an output.
5063 */
5064 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5065
f7ace40d 5066 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5076
f7ace40d
JW
5077 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5078 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5079 /* Unmute Line1 pin widget output buffer since it starts as an output.
5080 * If the pin mode is changed by the user the pin mode control will
5081 * take care of enabling the pin's input/output buffers as needed.
5082 * Therefore there's no need to enable the input buffer at this
5083 * stage.
cdcd9268 5084 */
f7ace40d 5085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5086 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5087 * mixer ctrl)
5088 */
f7ace40d
JW
5089 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5090
5091 /* Mute capture amp left and right */
5092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5093 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5094 * in (on mic1 pin)
5095 */
5096 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5097
5098 /* Do the same for the second ADC: mute capture input amp and
5099 * set ADC connection to line in (on mic1 pin)
5100 */
5101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5102 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5103
5104 /* Mute all inputs to mixer widget (even unconnected ones) */
5105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5113
5114 { }
a9430dd8
JW
5115};
5116
0bfc90e9
JW
5117/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5118 * similar laptops (adapted from Fujitsu init verbs).
5119 */
5120static struct hda_verb alc260_acer_init_verbs[] = {
5121 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5122 * the headphone jack. Turn this on and rely on the standard mute
5123 * methods whenever the user wants to turn these outputs off.
5124 */
5125 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5126 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5127 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5128 /* Internal speaker/Headphone jack is connected to Line-out pin */
5129 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5130 /* Internal microphone/Mic jack is connected to Mic1 pin */
5131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5132 /* Line In jack is connected to Line1 pin */
5133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5134 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5135 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5136 /* Ensure all other unused pins are disabled and muted. */
5137 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5140 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5143 /* Disable digital (SPDIF) pins */
5144 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5145 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5146
ea1fb29a 5147 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5148 * bus when acting as outputs.
5149 */
5150 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5151 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5152
5153 /* Start with output sum widgets muted and their output gains at min */
5154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5163
f12ab1e0
TI
5164 /* Unmute Line-out pin widget amp left and right
5165 * (no equiv mixer ctrl)
5166 */
0bfc90e9 5167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5168 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5169 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5170 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5171 * inputs. If the pin mode is changed by the user the pin mode control
5172 * will take care of enabling the pin's input/output buffers as needed.
5173 * Therefore there's no need to enable the input buffer at this
5174 * stage.
5175 */
5176 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5178
5179 /* Mute capture amp left and right */
5180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5181 /* Set ADC connection select to match default mixer setting - mic
5182 * (on mic1 pin)
5183 */
5184 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5185
5186 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5187 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5188 */
5189 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5190 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5191
5192 /* Mute all inputs to mixer widget (even unconnected ones) */
5193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5201
5202 { }
5203};
5204
cc959489
MS
5205/* Initialisation sequence for Maxdata Favorit 100XS
5206 * (adapted from Acer init verbs).
5207 */
5208static struct hda_verb alc260_favorit100_init_verbs[] = {
5209 /* GPIO 0 enables the output jack.
5210 * Turn this on and rely on the standard mute
5211 * methods whenever the user wants to turn these outputs off.
5212 */
5213 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5214 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5215 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5216 /* Line/Mic input jack is connected to Mic1 pin */
5217 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5218 /* Ensure all other unused pins are disabled and muted. */
5219 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5220 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5221 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5222 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5223 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5224 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5229 /* Disable digital (SPDIF) pins */
5230 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5231 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5232
5233 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5234 * bus when acting as outputs.
5235 */
5236 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5237 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5238
5239 /* Start with output sum widgets muted and their output gains at min */
5240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5246 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5249
5250 /* Unmute Line-out pin widget amp left and right
5251 * (no equiv mixer ctrl)
5252 */
5253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5254 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5255 * inputs. If the pin mode is changed by the user the pin mode control
5256 * will take care of enabling the pin's input/output buffers as needed.
5257 * Therefore there's no need to enable the input buffer at this
5258 * stage.
5259 */
5260 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5261
5262 /* Mute capture amp left and right */
5263 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5264 /* Set ADC connection select to match default mixer setting - mic
5265 * (on mic1 pin)
5266 */
5267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5268
5269 /* Do similar with the second ADC: mute capture input amp and
5270 * set ADC connection to mic to match ALSA's default state.
5271 */
5272 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5274
5275 /* Mute all inputs to mixer widget (even unconnected ones) */
5276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5284
5285 { }
5286};
5287
bc9f98a9
KY
5288static struct hda_verb alc260_will_verbs[] = {
5289 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5290 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5291 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5295 {}
5296};
5297
5298static struct hda_verb alc260_replacer_672v_verbs[] = {
5299 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5300 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5301 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5302
5303 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5304 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5305 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5306
5307 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5308 {}
5309};
5310
5311/* toggle speaker-output according to the hp-jack state */
5312static void alc260_replacer_672v_automute(struct hda_codec *codec)
5313{
5314 unsigned int present;
5315
5316 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5317 present = snd_hda_codec_read(codec, 0x0f, 0,
5318 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5319 if (present) {
82beb8fd
TI
5320 snd_hda_codec_write_cache(codec, 0x01, 0,
5321 AC_VERB_SET_GPIO_DATA, 1);
5322 snd_hda_codec_write_cache(codec, 0x0f, 0,
5323 AC_VERB_SET_PIN_WIDGET_CONTROL,
5324 PIN_HP);
bc9f98a9 5325 } else {
82beb8fd
TI
5326 snd_hda_codec_write_cache(codec, 0x01, 0,
5327 AC_VERB_SET_GPIO_DATA, 0);
5328 snd_hda_codec_write_cache(codec, 0x0f, 0,
5329 AC_VERB_SET_PIN_WIDGET_CONTROL,
5330 PIN_OUT);
bc9f98a9
KY
5331 }
5332}
5333
5334static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5335 unsigned int res)
5336{
5337 if ((res >> 26) == ALC880_HP_EVENT)
5338 alc260_replacer_672v_automute(codec);
5339}
5340
3f878308
KY
5341static struct hda_verb alc260_hp_dc7600_verbs[] = {
5342 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5343 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5344 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5345 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5346 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5348 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5349 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5350 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5351 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5352 {}
5353};
5354
7cf51e48
JW
5355/* Test configuration for debugging, modelled after the ALC880 test
5356 * configuration.
5357 */
5358#ifdef CONFIG_SND_DEBUG
5359static hda_nid_t alc260_test_dac_nids[1] = {
5360 0x02,
5361};
5362static hda_nid_t alc260_test_adc_nids[2] = {
5363 0x04, 0x05,
5364};
a1e8d2da 5365/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 5366 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 5367 * is NID 0x04.
17e7aec6 5368 */
a1e8d2da
JW
5369static struct hda_input_mux alc260_test_capture_sources[2] = {
5370 {
5371 .num_items = 7,
5372 .items = {
5373 { "MIC1 pin", 0x0 },
5374 { "MIC2 pin", 0x1 },
5375 { "LINE1 pin", 0x2 },
5376 { "LINE2 pin", 0x3 },
5377 { "CD pin", 0x4 },
5378 { "LINE-OUT pin", 0x5 },
5379 { "HP-OUT pin", 0x6 },
5380 },
5381 },
5382 {
5383 .num_items = 8,
5384 .items = {
5385 { "MIC1 pin", 0x0 },
5386 { "MIC2 pin", 0x1 },
5387 { "LINE1 pin", 0x2 },
5388 { "LINE2 pin", 0x3 },
5389 { "CD pin", 0x4 },
5390 { "Mixer", 0x5 },
5391 { "LINE-OUT pin", 0x6 },
5392 { "HP-OUT pin", 0x7 },
5393 },
7cf51e48
JW
5394 },
5395};
5396static struct snd_kcontrol_new alc260_test_mixer[] = {
5397 /* Output driver widgets */
5398 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5399 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5400 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5401 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5402 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5403 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5404
a1e8d2da
JW
5405 /* Modes for retasking pin widgets
5406 * Note: the ALC260 doesn't seem to act on requests to enable mic
5407 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5408 * mention this restriction. At this stage it's not clear whether
5409 * this behaviour is intentional or is a hardware bug in chip
5410 * revisions available at least up until early 2006. Therefore for
5411 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5412 * choices, but if it turns out that the lack of mic bias for these
5413 * NIDs is intentional we could change their modes from
5414 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5415 */
7cf51e48
JW
5416 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5417 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5418 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5419 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5420 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5421 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5422
5423 /* Loopback mixer controls */
5424 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5425 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5426 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5427 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5428 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5429 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5430 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5431 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5432 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5433 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
5434 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5435 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5436 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5437 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
5438
5439 /* Controls for GPIO pins, assuming they are configured as outputs */
5440 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5441 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5442 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5443 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5444
92621f13
JW
5445 /* Switches to allow the digital IO pins to be enabled. The datasheet
5446 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 5447 * make this output available should provide clarification.
92621f13
JW
5448 */
5449 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5450 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5451
f8225f6d
JW
5452 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5453 * this output to turn on an external amplifier.
5454 */
5455 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5456 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5457
7cf51e48
JW
5458 { } /* end */
5459};
5460static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
5461 /* Enable all GPIOs as outputs with an initial value of 0 */
5462 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5463 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5464 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5465
7cf51e48
JW
5466 /* Enable retasking pins as output, initially without power amp */
5467 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5468 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5470 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5471 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5473
92621f13
JW
5474 /* Disable digital (SPDIF) pins initially, but users can enable
5475 * them via a mixer switch. In the case of SPDIF-out, this initverb
5476 * payload also sets the generation to 0, output to be in "consumer"
5477 * PCM format, copyright asserted, no pre-emphasis and no validity
5478 * control.
5479 */
7cf51e48
JW
5480 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5481 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5482
ea1fb29a 5483 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5484 * OUT1 sum bus when acting as an output.
5485 */
5486 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5487 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5488 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5490
5491 /* Start with output sum widgets muted and their output gains at min */
5492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5501
cdcd9268
JW
5502 /* Unmute retasking pin widget output buffers since the default
5503 * state appears to be output. As the pin mode is changed by the
5504 * user the pin mode control will take care of enabling the pin's
5505 * input/output buffers as needed.
5506 */
7cf51e48
JW
5507 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5510 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5511 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5512 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5513 /* Also unmute the mono-out pin widget */
5514 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5515
7cf51e48
JW
5516 /* Mute capture amp left and right */
5517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5518 /* Set ADC connection select to match default mixer setting (mic1
5519 * pin)
7cf51e48
JW
5520 */
5521 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5522
5523 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5524 * set ADC connection to mic1 pin
7cf51e48
JW
5525 */
5526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5527 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5528
5529 /* Mute all inputs to mixer widget (even unconnected ones) */
5530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5538
5539 { }
5540};
5541#endif
5542
6330079f
TI
5543#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5544#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5545
a3bcba38
TI
5546#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5547#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5548
df694daa
KY
5549/*
5550 * for BIOS auto-configuration
5551 */
16ded525 5552
df694daa 5553static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5554 const char *pfx, int *vol_bits)
df694daa
KY
5555{
5556 hda_nid_t nid_vol;
5557 unsigned long vol_val, sw_val;
5558 char name[32];
5559 int err;
5560
5561 if (nid >= 0x0f && nid < 0x11) {
5562 nid_vol = nid - 0x7;
5563 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5564 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5565 } else if (nid == 0x11) {
5566 nid_vol = nid - 0x7;
5567 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5568 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5569 } else if (nid >= 0x12 && nid <= 0x15) {
5570 nid_vol = 0x08;
5571 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5572 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5573 } else
5574 return 0; /* N/A */
ea1fb29a 5575
863b4518
TI
5576 if (!(*vol_bits & (1 << nid_vol))) {
5577 /* first control for the volume widget */
5578 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5579 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5580 if (err < 0)
5581 return err;
5582 *vol_bits |= (1 << nid_vol);
5583 }
df694daa 5584 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
5585 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5586 if (err < 0)
df694daa
KY
5587 return err;
5588 return 1;
5589}
5590
5591/* add playback controls from the parsed DAC table */
5592static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5593 const struct auto_pin_cfg *cfg)
5594{
5595 hda_nid_t nid;
5596 int err;
863b4518 5597 int vols = 0;
df694daa
KY
5598
5599 spec->multiout.num_dacs = 1;
5600 spec->multiout.dac_nids = spec->private_dac_nids;
5601 spec->multiout.dac_nids[0] = 0x02;
5602
5603 nid = cfg->line_out_pins[0];
5604 if (nid) {
863b4518 5605 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
df694daa
KY
5606 if (err < 0)
5607 return err;
5608 }
5609
82bc955f 5610 nid = cfg->speaker_pins[0];
df694daa 5611 if (nid) {
863b4518 5612 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
5613 if (err < 0)
5614 return err;
5615 }
5616
eb06ed8f 5617 nid = cfg->hp_pins[0];
df694daa 5618 if (nid) {
863b4518
TI
5619 err = alc260_add_playback_controls(spec, nid, "Headphone",
5620 &vols);
df694daa
KY
5621 if (err < 0)
5622 return err;
5623 }
f12ab1e0 5624 return 0;
df694daa
KY
5625}
5626
5627/* create playback/capture controls for input pins */
5628static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5629 const struct auto_pin_cfg *cfg)
5630{
61b9b9b1 5631 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
5632 int i, err, idx;
5633
5634 for (i = 0; i < AUTO_PIN_LAST; i++) {
5635 if (cfg->input_pins[i] >= 0x12) {
5636 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5637 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5638 auto_pin_cfg_labels[i], idx,
5639 0x07);
df694daa
KY
5640 if (err < 0)
5641 return err;
f12ab1e0
TI
5642 imux->items[imux->num_items].label =
5643 auto_pin_cfg_labels[i];
df694daa
KY
5644 imux->items[imux->num_items].index = idx;
5645 imux->num_items++;
5646 }
f12ab1e0 5647 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5648 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5649 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5650 auto_pin_cfg_labels[i], idx,
5651 0x07);
df694daa
KY
5652 if (err < 0)
5653 return err;
f12ab1e0
TI
5654 imux->items[imux->num_items].label =
5655 auto_pin_cfg_labels[i];
df694daa
KY
5656 imux->items[imux->num_items].index = idx;
5657 imux->num_items++;
5658 }
5659 }
5660 return 0;
5661}
5662
5663static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5664 hda_nid_t nid, int pin_type,
5665 int sel_idx)
5666{
f6c7e546 5667 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5668 /* need the manual connection? */
5669 if (nid >= 0x12) {
5670 int idx = nid - 0x12;
5671 snd_hda_codec_write(codec, idx + 0x0b, 0,
5672 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5673 }
5674}
5675
5676static void alc260_auto_init_multi_out(struct hda_codec *codec)
5677{
5678 struct alc_spec *spec = codec->spec;
5679 hda_nid_t nid;
5680
bc9f98a9 5681 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 5682 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5683 if (nid) {
5684 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5685 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5686 }
ea1fb29a 5687
82bc955f 5688 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5689 if (nid)
5690 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5691
eb06ed8f 5692 nid = spec->autocfg.hp_pins[0];
df694daa 5693 if (nid)
baba8ee9 5694 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5695}
df694daa
KY
5696
5697#define ALC260_PIN_CD_NID 0x16
5698static void alc260_auto_init_analog_input(struct hda_codec *codec)
5699{
5700 struct alc_spec *spec = codec->spec;
5701 int i;
5702
5703 for (i = 0; i < AUTO_PIN_LAST; i++) {
5704 hda_nid_t nid = spec->autocfg.input_pins[i];
5705 if (nid >= 0x12) {
23f0c048 5706 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5707 if (nid != ALC260_PIN_CD_NID &&
5708 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5709 snd_hda_codec_write(codec, nid, 0,
5710 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5711 AMP_OUT_MUTE);
5712 }
5713 }
5714}
5715
5716/*
5717 * generic initialization of ADC, input mixers and output mixers
5718 */
5719static struct hda_verb alc260_volume_init_verbs[] = {
5720 /*
5721 * Unmute ADC0-1 and set the default input to mic-in
5722 */
5723 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5724 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5725 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5726 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5727
df694daa
KY
5728 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5729 * mixer widget
f12ab1e0
TI
5730 * Note: PASD motherboards uses the Line In 2 as the input for
5731 * front panel mic (mic 2)
df694daa
KY
5732 */
5733 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5734 /* mute analog inputs */
5735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5740
5741 /*
5742 * Set up output mixers (0x08 - 0x0a)
5743 */
5744 /* set vol=0 to output mixers */
5745 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5747 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5748 /* set up input amps for analog loopback */
5749 /* Amp Indices: DAC = 0, mixer = 1 */
5750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5752 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5754 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5755 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5756
df694daa
KY
5757 { }
5758};
5759
5760static int alc260_parse_auto_config(struct hda_codec *codec)
5761{
5762 struct alc_spec *spec = codec->spec;
df694daa
KY
5763 int err;
5764 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5765
f12ab1e0
TI
5766 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5767 alc260_ignore);
5768 if (err < 0)
df694daa 5769 return err;
f12ab1e0
TI
5770 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5771 if (err < 0)
4a471b7d 5772 return err;
603c4019 5773 if (!spec->kctls.list)
df694daa 5774 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5775 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5776 if (err < 0)
df694daa
KY
5777 return err;
5778
5779 spec->multiout.max_channels = 2;
5780
0852d7a6 5781 if (spec->autocfg.dig_outs)
df694daa 5782 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 5783 if (spec->kctls.list)
d88897ea 5784 add_mixer(spec, spec->kctls.list);
df694daa 5785
d88897ea 5786 add_verb(spec, alc260_volume_init_verbs);
df694daa 5787
a1e8d2da 5788 spec->num_mux_defs = 1;
61b9b9b1 5789 spec->input_mux = &spec->private_imux[0];
df694daa 5790
df694daa
KY
5791 return 1;
5792}
5793
ae6b813a
TI
5794/* additional initialization for auto-configuration model */
5795static void alc260_auto_init(struct hda_codec *codec)
df694daa 5796{
f6c7e546 5797 struct alc_spec *spec = codec->spec;
df694daa
KY
5798 alc260_auto_init_multi_out(codec);
5799 alc260_auto_init_analog_input(codec);
f6c7e546 5800 if (spec->unsol_event)
7fb0d78f 5801 alc_inithook(codec);
df694daa
KY
5802}
5803
cb53c626
TI
5804#ifdef CONFIG_SND_HDA_POWER_SAVE
5805static struct hda_amp_list alc260_loopbacks[] = {
5806 { 0x07, HDA_INPUT, 0 },
5807 { 0x07, HDA_INPUT, 1 },
5808 { 0x07, HDA_INPUT, 2 },
5809 { 0x07, HDA_INPUT, 3 },
5810 { 0x07, HDA_INPUT, 4 },
5811 { } /* end */
5812};
5813#endif
5814
df694daa
KY
5815/*
5816 * ALC260 configurations
5817 */
f5fcc13c
TI
5818static const char *alc260_models[ALC260_MODEL_LAST] = {
5819 [ALC260_BASIC] = "basic",
5820 [ALC260_HP] = "hp",
5821 [ALC260_HP_3013] = "hp-3013",
2922c9af 5822 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
5823 [ALC260_FUJITSU_S702X] = "fujitsu",
5824 [ALC260_ACER] = "acer",
bc9f98a9
KY
5825 [ALC260_WILL] = "will",
5826 [ALC260_REPLACER_672V] = "replacer",
cc959489 5827 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 5828#ifdef CONFIG_SND_DEBUG
f5fcc13c 5829 [ALC260_TEST] = "test",
7cf51e48 5830#endif
f5fcc13c
TI
5831 [ALC260_AUTO] = "auto",
5832};
5833
5834static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5835 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5836 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 5837 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 5838 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5839 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 5840 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 5841 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 5842 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
5843 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5844 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5845 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5846 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5847 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5848 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5849 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5850 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5851 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5852 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5853 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5854 {}
5855};
5856
5857static struct alc_config_preset alc260_presets[] = {
5858 [ALC260_BASIC] = {
5859 .mixers = { alc260_base_output_mixer,
45bdd1c1 5860 alc260_input_mixer },
df694daa
KY
5861 .init_verbs = { alc260_init_verbs },
5862 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5863 .dac_nids = alc260_dac_nids,
f9e336f6 5864 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
5865 .adc_nids = alc260_adc_nids,
5866 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5867 .channel_mode = alc260_modes,
5868 .input_mux = &alc260_capture_source,
5869 },
5870 [ALC260_HP] = {
bec15c3a 5871 .mixers = { alc260_hp_output_mixer,
f9e336f6 5872 alc260_input_mixer },
bec15c3a
TI
5873 .init_verbs = { alc260_init_verbs,
5874 alc260_hp_unsol_verbs },
df694daa
KY
5875 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5876 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5877 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5878 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
5879 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5880 .channel_mode = alc260_modes,
5881 .input_mux = &alc260_capture_source,
bec15c3a
TI
5882 .unsol_event = alc260_hp_unsol_event,
5883 .init_hook = alc260_hp_automute,
df694daa 5884 },
3f878308
KY
5885 [ALC260_HP_DC7600] = {
5886 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 5887 alc260_input_mixer },
3f878308
KY
5888 .init_verbs = { alc260_init_verbs,
5889 alc260_hp_dc7600_verbs },
5890 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5891 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5892 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5893 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
5894 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5895 .channel_mode = alc260_modes,
5896 .input_mux = &alc260_capture_source,
5897 .unsol_event = alc260_hp_3012_unsol_event,
5898 .init_hook = alc260_hp_3012_automute,
5899 },
df694daa
KY
5900 [ALC260_HP_3013] = {
5901 .mixers = { alc260_hp_3013_mixer,
f9e336f6 5902 alc260_input_mixer },
bec15c3a
TI
5903 .init_verbs = { alc260_hp_3013_init_verbs,
5904 alc260_hp_3013_unsol_verbs },
df694daa
KY
5905 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5906 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5907 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5908 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
5909 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5910 .channel_mode = alc260_modes,
5911 .input_mux = &alc260_capture_source,
bec15c3a
TI
5912 .unsol_event = alc260_hp_3013_unsol_event,
5913 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5914 },
5915 [ALC260_FUJITSU_S702X] = {
f9e336f6 5916 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
5917 .init_verbs = { alc260_fujitsu_init_verbs },
5918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5919 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5921 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5923 .channel_mode = alc260_modes,
a1e8d2da
JW
5924 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5925 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5926 },
0bfc90e9 5927 [ALC260_ACER] = {
f9e336f6 5928 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
5929 .init_verbs = { alc260_acer_init_verbs },
5930 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5931 .dac_nids = alc260_dac_nids,
5932 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5933 .adc_nids = alc260_dual_adc_nids,
5934 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5935 .channel_mode = alc260_modes,
a1e8d2da
JW
5936 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5937 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5938 },
cc959489
MS
5939 [ALC260_FAVORIT100] = {
5940 .mixers = { alc260_favorit100_mixer },
5941 .init_verbs = { alc260_favorit100_init_verbs },
5942 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5943 .dac_nids = alc260_dac_nids,
5944 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5945 .adc_nids = alc260_dual_adc_nids,
5946 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5947 .channel_mode = alc260_modes,
5948 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5949 .input_mux = alc260_favorit100_capture_sources,
5950 },
bc9f98a9 5951 [ALC260_WILL] = {
f9e336f6 5952 .mixers = { alc260_will_mixer },
bc9f98a9
KY
5953 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5954 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5955 .dac_nids = alc260_dac_nids,
5956 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5957 .adc_nids = alc260_adc_nids,
5958 .dig_out_nid = ALC260_DIGOUT_NID,
5959 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5960 .channel_mode = alc260_modes,
5961 .input_mux = &alc260_capture_source,
5962 },
5963 [ALC260_REPLACER_672V] = {
f9e336f6 5964 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
5965 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5966 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5967 .dac_nids = alc260_dac_nids,
5968 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5969 .adc_nids = alc260_adc_nids,
5970 .dig_out_nid = ALC260_DIGOUT_NID,
5971 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5972 .channel_mode = alc260_modes,
5973 .input_mux = &alc260_capture_source,
5974 .unsol_event = alc260_replacer_672v_unsol_event,
5975 .init_hook = alc260_replacer_672v_automute,
5976 },
7cf51e48
JW
5977#ifdef CONFIG_SND_DEBUG
5978 [ALC260_TEST] = {
f9e336f6 5979 .mixers = { alc260_test_mixer },
7cf51e48
JW
5980 .init_verbs = { alc260_test_init_verbs },
5981 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5982 .dac_nids = alc260_test_dac_nids,
5983 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5984 .adc_nids = alc260_test_adc_nids,
5985 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5986 .channel_mode = alc260_modes,
a1e8d2da
JW
5987 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5988 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5989 },
5990#endif
df694daa
KY
5991};
5992
5993static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5994{
5995 struct alc_spec *spec;
df694daa 5996 int err, board_config;
1da177e4 5997
e560d8d8 5998 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5999 if (spec == NULL)
6000 return -ENOMEM;
6001
6002 codec->spec = spec;
6003
f5fcc13c
TI
6004 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6005 alc260_models,
6006 alc260_cfg_tbl);
6007 if (board_config < 0) {
9c7f852e
TI
6008 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6009 "trying auto-probe from BIOS...\n");
df694daa 6010 board_config = ALC260_AUTO;
16ded525 6011 }
1da177e4 6012
df694daa
KY
6013 if (board_config == ALC260_AUTO) {
6014 /* automatic parse from the BIOS config */
6015 err = alc260_parse_auto_config(codec);
6016 if (err < 0) {
6017 alc_free(codec);
6018 return err;
f12ab1e0 6019 } else if (!err) {
9c7f852e
TI
6020 printk(KERN_INFO
6021 "hda_codec: Cannot set up configuration "
6022 "from BIOS. Using base mode...\n");
df694daa
KY
6023 board_config = ALC260_BASIC;
6024 }
a9430dd8 6025 }
e9edcee0 6026
680cd536
KK
6027 err = snd_hda_attach_beep_device(codec, 0x1);
6028 if (err < 0) {
6029 alc_free(codec);
6030 return err;
6031 }
6032
df694daa
KY
6033 if (board_config != ALC260_AUTO)
6034 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
6035
6036 spec->stream_name_analog = "ALC260 Analog";
6037 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6038 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6039
a3bcba38
TI
6040 spec->stream_name_digital = "ALC260 Digital";
6041 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6042 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6043
4ef0ef19
TI
6044 if (!spec->adc_nids && spec->input_mux) {
6045 /* check whether NID 0x04 is valid */
6046 unsigned int wcap = get_wcaps(codec, 0x04);
6047 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6048 /* get type */
6049 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6050 spec->adc_nids = alc260_adc_nids_alt;
6051 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6052 } else {
6053 spec->adc_nids = alc260_adc_nids;
6054 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6055 }
6056 }
f9e336f6 6057 set_capture_mixer(spec);
45bdd1c1 6058 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6059
2134ea4f
TI
6060 spec->vmaster_nid = 0x08;
6061
1da177e4 6062 codec->patch_ops = alc_patch_ops;
df694daa 6063 if (board_config == ALC260_AUTO)
ae6b813a 6064 spec->init_hook = alc260_auto_init;
cb53c626
TI
6065#ifdef CONFIG_SND_HDA_POWER_SAVE
6066 if (!spec->loopback.amplist)
6067 spec->loopback.amplist = alc260_loopbacks;
6068#endif
daead538 6069 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
6070
6071 return 0;
6072}
6073
e9edcee0 6074
1da177e4
LT
6075/*
6076 * ALC882 support
6077 *
6078 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6079 * configuration. Each pin widget can choose any input DACs and a mixer.
6080 * Each ADC is connected from a mixer of all inputs. This makes possible
6081 * 6-channel independent captures.
6082 *
6083 * In addition, an independent DAC for the multi-playback (not used in this
6084 * driver yet).
6085 */
df694daa
KY
6086#define ALC882_DIGOUT_NID 0x06
6087#define ALC882_DIGIN_NID 0x0a
1da177e4 6088
d2a6d7dc 6089static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6090 { 8, NULL }
6091};
6092
6093static hda_nid_t alc882_dac_nids[4] = {
6094 /* front, rear, clfe, rear_surr */
6095 0x02, 0x03, 0x04, 0x05
6096};
6097
df694daa
KY
6098/* identical with ALC880 */
6099#define alc882_adc_nids alc880_adc_nids
6100#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 6101
e1406348
TI
6102static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6103static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6104
1da177e4
LT
6105/* input MUX */
6106/* FIXME: should be a matrix-type input source selection */
6107
6108static struct hda_input_mux alc882_capture_source = {
6109 .num_items = 4,
6110 .items = {
6111 { "Mic", 0x0 },
6112 { "Front Mic", 0x1 },
6113 { "Line", 0x2 },
6114 { "CD", 0x4 },
6115 },
6116};
272a527c
KY
6117/*
6118 * 2ch mode
6119 */
6120static struct hda_verb alc882_3ST_ch2_init[] = {
6121 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6122 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6123 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6124 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6125 { } /* end */
6126};
6127
6128/*
6129 * 6ch mode
6130 */
6131static struct hda_verb alc882_3ST_ch6_init[] = {
6132 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6133 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6134 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6137 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6138 { } /* end */
6139};
6140
6141static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6142 { 2, alc882_3ST_ch2_init },
6143 { 6, alc882_3ST_ch6_init },
6144};
6145
df694daa
KY
6146/*
6147 * 6ch mode
6148 */
6149static struct hda_verb alc882_sixstack_ch6_init[] = {
6150 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6151 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6152 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6153 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6154 { } /* end */
6155};
6156
6157/*
6158 * 8ch mode
6159 */
6160static struct hda_verb alc882_sixstack_ch8_init[] = {
6161 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6162 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6163 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6164 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6165 { } /* end */
6166};
6167
6168static struct hda_channel_mode alc882_sixstack_modes[2] = {
6169 { 6, alc882_sixstack_ch6_init },
6170 { 8, alc882_sixstack_ch8_init },
6171};
6172
87350ad0
TI
6173/*
6174 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6175 */
6176
6177/*
6178 * 2ch mode
6179 */
6180static struct hda_verb alc885_mbp_ch2_init[] = {
6181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6182 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6183 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6184 { } /* end */
6185};
6186
6187/*
6188 * 6ch mode
6189 */
6190static struct hda_verb alc885_mbp_ch6_init[] = {
6191 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6192 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6193 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6194 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6195 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6196 { } /* end */
6197};
6198
6199static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6200 { 2, alc885_mbp_ch2_init },
6201 { 6, alc885_mbp_ch6_init },
6202};
6203
6204
1da177e4
LT
6205/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6206 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6207 */
c8b6bf9b 6208static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 6209 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 6210 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 6211 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 6212 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
6213 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6214 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
6215 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6216 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 6217 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 6218 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
6219 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6225 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
6226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6228 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 6229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
6230 { } /* end */
6231};
6232
87350ad0 6233static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
6234 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6235 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6236 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6237 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6239 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
6240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6241 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 6242 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
6243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6244 { } /* end */
6245};
bdd148a3
KY
6246static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6247 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6248 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6249 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6250 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
6256 { } /* end */
6257};
6258
272a527c
KY
6259static struct snd_kcontrol_new alc882_targa_mixer[] = {
6260 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6261 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6262 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6263 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6264 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6269 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6270 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6271 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 6272 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
6273 { } /* end */
6274};
6275
6276/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6277 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6278 */
6279static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6283 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6288 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6289 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6290 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6293 { } /* end */
6294};
6295
914759b7
TI
6296static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6297 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6298 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6305 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
6307 { } /* end */
6308};
6309
df694daa
KY
6310static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6311 {
6312 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6313 .name = "Channel Mode",
6314 .info = alc_ch_mode_info,
6315 .get = alc_ch_mode_get,
6316 .put = alc_ch_mode_put,
6317 },
6318 { } /* end */
6319};
6320
1da177e4
LT
6321static struct hda_verb alc882_init_verbs[] = {
6322 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
6323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6326 /* Rear mixer */
05acb863
TI
6327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6328 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6329 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6330 /* CLFE mixer */
05acb863
TI
6331 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6332 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6334 /* Side mixer */
05acb863
TI
6335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6338
e9edcee0 6339 /* Front Pin: output 0 (0x0c) */
05acb863 6340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6342 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 6343 /* Rear Pin: output 1 (0x0d) */
05acb863 6344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 6347 /* CLFE Pin: output 2 (0x0e) */
05acb863 6348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6349 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6350 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 6351 /* Side Pin: output 3 (0x0f) */
05acb863 6352 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6353 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6354 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 6355 /* Mic (rear) pin: input vref at 80% */
16ded525 6356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6358 /* Front Mic pin: input vref at 80% */
16ded525 6359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6361 /* Line In pin: input */
05acb863 6362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
6363 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6364 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6367 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6368 /* CD pin widget for input */
05acb863 6369 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
6370
6371 /* FIXME: use matrix-type input source selection */
6372 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6373 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
6374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6378 /* Input mixer2 */
05acb863
TI
6379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6383 /* Input mixer3 */
05acb863
TI
6384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6388 /* ADC1: mute amp left and right */
6389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6390 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6391 /* ADC2: mute amp left and right */
6392 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6394 /* ADC3: mute amp left and right */
6395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6396 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
6397
6398 { }
6399};
6400
4b146cb0
TI
6401static struct hda_verb alc882_eapd_verbs[] = {
6402 /* change to EAPD mode */
6403 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 6404 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 6405 { }
4b146cb0
TI
6406};
6407
9102cd1c
TD
6408/* Mac Pro test */
6409static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6410 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6411 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6412 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 6415 /* FIXME: this looks suspicious...
9102cd1c
TD
6416 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6417 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 6418 */
9102cd1c
TD
6419 { } /* end */
6420};
6421
6422static struct hda_verb alc882_macpro_init_verbs[] = {
6423 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6427 /* Front Pin: output 0 (0x0c) */
6428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6431 /* Front Mic pin: input vref at 80% */
6432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6434 /* Speaker: output */
6435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6438 /* Headphone output (output 0 - 0x0c) */
6439 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6440 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6441 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6442
6443 /* FIXME: use matrix-type input source selection */
6444 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6445 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6450 /* Input mixer2 */
6451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6455 /* Input mixer3 */
6456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6460 /* ADC1: mute amp left and right */
6461 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6462 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6463 /* ADC2: mute amp left and right */
6464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6466 /* ADC3: mute amp left and right */
6467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6468 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6469
6470 { }
6471};
f12ab1e0 6472
87350ad0
TI
6473/* Macbook Pro rev3 */
6474static struct hda_verb alc885_mbp3_init_verbs[] = {
6475 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6479 /* Rear mixer */
6480 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6483 /* Front Pin: output 0 (0x0c) */
6484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6486 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6487 /* HP Pin: output 0 (0x0d) */
6488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6492 /* Mic (rear) pin: input vref at 80% */
6493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6495 /* Front Mic pin: input vref at 80% */
6496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6498 /* Line In pin: use output 1 when in LineOut mode */
6499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6500 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6501 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6502
6503 /* FIXME: use matrix-type input source selection */
6504 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6505 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6510 /* Input mixer2 */
6511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6515 /* Input mixer3 */
6516 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6520 /* ADC1: mute amp left and right */
6521 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6522 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6523 /* ADC2: mute amp left and right */
6524 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6525 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6526 /* ADC3: mute amp left and right */
6527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6529
6530 { }
6531};
6532
c54728d8
NF
6533/* iMac 24 mixer. */
6534static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6535 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6536 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6537 { } /* end */
6538};
6539
6540/* iMac 24 init verbs. */
6541static struct hda_verb alc885_imac24_init_verbs[] = {
6542 /* Internal speakers: output 0 (0x0c) */
6543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6546 /* Internal speakers: output 0 (0x0c) */
6547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6549 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6550 /* Headphone: output 0 (0x0c) */
6551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6552 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6553 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6554 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6555 /* Front Mic: input vref at 80% */
6556 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6557 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6558 { }
6559};
6560
6561/* Toggle speaker-output according to the hp-jack state */
6562static void alc885_imac24_automute(struct hda_codec *codec)
6563{
6564 unsigned int present;
6565
6566 present = snd_hda_codec_read(codec, 0x14, 0,
6567 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6568 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6569 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6570 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6571 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
6572}
6573
6574/* Processes unsolicited events. */
6575static void alc885_imac24_unsol_event(struct hda_codec *codec,
6576 unsigned int res)
6577{
6578 /* Headphone insertion or removal. */
6579 if ((res >> 26) == ALC880_HP_EVENT)
6580 alc885_imac24_automute(codec);
6581}
6582
87350ad0
TI
6583static void alc885_mbp3_automute(struct hda_codec *codec)
6584{
6585 unsigned int present;
6586
6587 present = snd_hda_codec_read(codec, 0x15, 0,
6588 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6589 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6590 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6591 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6592 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6593
6594}
6595static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6596 unsigned int res)
6597{
6598 /* Headphone insertion or removal. */
6599 if ((res >> 26) == ALC880_HP_EVENT)
6600 alc885_mbp3_automute(codec);
6601}
6602
6603
272a527c
KY
6604static struct hda_verb alc882_targa_verbs[] = {
6605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6607
6608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6609 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6610
272a527c
KY
6611 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6613 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6614
6615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6616 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6617 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6618 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6619 { } /* end */
6620};
6621
6622/* toggle speaker-output according to the hp-jack state */
6623static void alc882_targa_automute(struct hda_codec *codec)
6624{
6625 unsigned int present;
ea1fb29a 6626
272a527c
KY
6627 present = snd_hda_codec_read(codec, 0x14, 0,
6628 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6629 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6630 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
6631 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6632 present ? 1 : 3);
272a527c
KY
6633}
6634
6635static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6636{
6637 /* Looks like the unsol event is incompatible with the standard
6638 * definition. 4bit tag is placed at 26 bit!
6639 */
6640 if (((res >> 26) == ALC880_HP_EVENT)) {
6641 alc882_targa_automute(codec);
6642 }
6643}
6644
6645static struct hda_verb alc882_asus_a7j_verbs[] = {
6646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6648
6649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6651 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6652
272a527c
KY
6653 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6655 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6656
6657 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6658 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6659 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6660 { } /* end */
6661};
6662
914759b7
TI
6663static struct hda_verb alc882_asus_a7m_verbs[] = {
6664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6666
6667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6669 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6670
914759b7
TI
6671 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6673 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6674
6675 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6676 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6677 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6678 { } /* end */
6679};
6680
9102cd1c
TD
6681static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6682{
6683 unsigned int gpiostate, gpiomask, gpiodir;
6684
6685 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6686 AC_VERB_GET_GPIO_DATA, 0);
6687
6688 if (!muted)
6689 gpiostate |= (1 << pin);
6690 else
6691 gpiostate &= ~(1 << pin);
6692
6693 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6694 AC_VERB_GET_GPIO_MASK, 0);
6695 gpiomask |= (1 << pin);
6696
6697 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6698 AC_VERB_GET_GPIO_DIRECTION, 0);
6699 gpiodir |= (1 << pin);
6700
6701
6702 snd_hda_codec_write(codec, codec->afg, 0,
6703 AC_VERB_SET_GPIO_MASK, gpiomask);
6704 snd_hda_codec_write(codec, codec->afg, 0,
6705 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6706
6707 msleep(1);
6708
6709 snd_hda_codec_write(codec, codec->afg, 0,
6710 AC_VERB_SET_GPIO_DATA, gpiostate);
6711}
6712
7debbe51
TI
6713/* set up GPIO at initialization */
6714static void alc885_macpro_init_hook(struct hda_codec *codec)
6715{
6716 alc882_gpio_mute(codec, 0, 0);
6717 alc882_gpio_mute(codec, 1, 0);
6718}
6719
6720/* set up GPIO and update auto-muting at initialization */
6721static void alc885_imac24_init_hook(struct hda_codec *codec)
6722{
6723 alc885_macpro_init_hook(codec);
6724 alc885_imac24_automute(codec);
6725}
6726
df694daa
KY
6727/*
6728 * generic initialization of ADC, input mixers and output mixers
6729 */
6730static struct hda_verb alc882_auto_init_verbs[] = {
6731 /*
6732 * Unmute ADC0-2 and set the default input to mic-in
6733 */
6734 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6740
cb53c626 6741 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6742 * mixer widget
f12ab1e0
TI
6743 * Note: PASD motherboards uses the Line In 2 as the input for
6744 * front panel mic (mic 2)
df694daa
KY
6745 */
6746 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 6752
df694daa
KY
6753 /*
6754 * Set up output mixers (0x0c - 0x0f)
6755 */
6756 /* set vol=0 to output mixers */
6757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6758 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6761 /* set up input amps for analog loopback */
6762 /* Amp Indices: DAC = 0, mixer = 1 */
6763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6771 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6773
6774 /* FIXME: use matrix-type input source selection */
6775 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6776 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6781 /* Input mixer2 */
6782 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6786 /* Input mixer3 */
6787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6791
6792 { }
6793};
6794
cb53c626
TI
6795#ifdef CONFIG_SND_HDA_POWER_SAVE
6796#define alc882_loopbacks alc880_loopbacks
6797#endif
6798
df694daa
KY
6799/* pcm configuration: identiacal with ALC880 */
6800#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6801#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6802#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6803#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6804
6805/*
6806 * configuration and preset
6807 */
f5fcc13c
TI
6808static const char *alc882_models[ALC882_MODEL_LAST] = {
6809 [ALC882_3ST_DIG] = "3stack-dig",
6810 [ALC882_6ST_DIG] = "6stack-dig",
6811 [ALC882_ARIMA] = "arima",
bdd148a3 6812 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6813 [ALC882_TARGA] = "targa",
6814 [ALC882_ASUS_A7J] = "asus-a7j",
6815 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6816 [ALC885_MACPRO] = "macpro",
87350ad0 6817 [ALC885_MBP3] = "mbp3",
c54728d8 6818 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6819 [ALC882_AUTO] = "auto",
6820};
6821
6822static struct snd_pci_quirk alc882_cfg_tbl[] = {
6823 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6824 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6825 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6826 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6827 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6828 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6829 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6830 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6831 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6832 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6833 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6834 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6835 {}
6836};
6837
6838static struct alc_config_preset alc882_presets[] = {
6839 [ALC882_3ST_DIG] = {
6840 .mixers = { alc882_base_mixer },
6841 .init_verbs = { alc882_init_verbs },
6842 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6843 .dac_nids = alc882_dac_nids,
6844 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6845 .dig_in_nid = ALC882_DIGIN_NID,
6846 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6847 .channel_mode = alc882_ch_modes,
4e195a7b 6848 .need_dac_fix = 1,
df694daa
KY
6849 .input_mux = &alc882_capture_source,
6850 },
6851 [ALC882_6ST_DIG] = {
6852 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6853 .init_verbs = { alc882_init_verbs },
6854 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6855 .dac_nids = alc882_dac_nids,
6856 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6857 .dig_in_nid = ALC882_DIGIN_NID,
6858 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6859 .channel_mode = alc882_sixstack_modes,
6860 .input_mux = &alc882_capture_source,
6861 },
4b146cb0
TI
6862 [ALC882_ARIMA] = {
6863 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6864 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6865 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6866 .dac_nids = alc882_dac_nids,
6867 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6868 .channel_mode = alc882_sixstack_modes,
6869 .input_mux = &alc882_capture_source,
6870 },
bdd148a3
KY
6871 [ALC882_W2JC] = {
6872 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6873 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6874 alc880_gpio1_init_verbs },
6875 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6876 .dac_nids = alc882_dac_nids,
6877 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6878 .channel_mode = alc880_threestack_modes,
6879 .need_dac_fix = 1,
6880 .input_mux = &alc882_capture_source,
6881 .dig_out_nid = ALC882_DIGOUT_NID,
6882 },
87350ad0
TI
6883 [ALC885_MBP3] = {
6884 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6885 .init_verbs = { alc885_mbp3_init_verbs,
6886 alc880_gpio1_init_verbs },
6887 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6888 .dac_nids = alc882_dac_nids,
6889 .channel_mode = alc885_mbp_6ch_modes,
6890 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6891 .input_mux = &alc882_capture_source,
6892 .dig_out_nid = ALC882_DIGOUT_NID,
6893 .dig_in_nid = ALC882_DIGIN_NID,
6894 .unsol_event = alc885_mbp3_unsol_event,
6895 .init_hook = alc885_mbp3_automute,
6896 },
9102cd1c
TD
6897 [ALC885_MACPRO] = {
6898 .mixers = { alc882_macpro_mixer },
6899 .init_verbs = { alc882_macpro_init_verbs },
6900 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6901 .dac_nids = alc882_dac_nids,
6902 .dig_out_nid = ALC882_DIGOUT_NID,
6903 .dig_in_nid = ALC882_DIGIN_NID,
6904 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6905 .channel_mode = alc882_ch_modes,
6906 .input_mux = &alc882_capture_source,
7debbe51 6907 .init_hook = alc885_macpro_init_hook,
9102cd1c 6908 },
c54728d8
NF
6909 [ALC885_IMAC24] = {
6910 .mixers = { alc885_imac24_mixer },
6911 .init_verbs = { alc885_imac24_init_verbs },
6912 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6913 .dac_nids = alc882_dac_nids,
6914 .dig_out_nid = ALC882_DIGOUT_NID,
6915 .dig_in_nid = ALC882_DIGIN_NID,
6916 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6917 .channel_mode = alc882_ch_modes,
6918 .input_mux = &alc882_capture_source,
6919 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6920 .init_hook = alc885_imac24_init_hook,
c54728d8 6921 },
272a527c 6922 [ALC882_TARGA] = {
f9e336f6 6923 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
272a527c
KY
6924 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6925 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6926 .dac_nids = alc882_dac_nids,
6927 .dig_out_nid = ALC882_DIGOUT_NID,
6928 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6929 .adc_nids = alc882_adc_nids,
e1406348 6930 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6931 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6932 .channel_mode = alc882_3ST_6ch_modes,
6933 .need_dac_fix = 1,
6934 .input_mux = &alc882_capture_source,
6935 .unsol_event = alc882_targa_unsol_event,
6936 .init_hook = alc882_targa_automute,
6937 },
6938 [ALC882_ASUS_A7J] = {
f9e336f6 6939 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
272a527c
KY
6940 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6941 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6942 .dac_nids = alc882_dac_nids,
6943 .dig_out_nid = ALC882_DIGOUT_NID,
6944 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6945 .adc_nids = alc882_adc_nids,
e1406348 6946 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6947 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6948 .channel_mode = alc882_3ST_6ch_modes,
6949 .need_dac_fix = 1,
6950 .input_mux = &alc882_capture_source,
ea1fb29a 6951 },
914759b7
TI
6952 [ALC882_ASUS_A7M] = {
6953 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6954 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6955 alc880_gpio1_init_verbs,
6956 alc882_asus_a7m_verbs },
6957 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6958 .dac_nids = alc882_dac_nids,
6959 .dig_out_nid = ALC882_DIGOUT_NID,
6960 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6961 .channel_mode = alc880_threestack_modes,
6962 .need_dac_fix = 1,
6963 .input_mux = &alc882_capture_source,
ea1fb29a 6964 },
df694daa
KY
6965};
6966
6967
f95474ec
TI
6968/*
6969 * Pin config fixes
6970 */
ea1fb29a 6971enum {
f95474ec
TI
6972 PINFIX_ABIT_AW9D_MAX
6973};
6974
6975static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6976 { 0x15, 0x01080104 }, /* side */
6977 { 0x16, 0x01011012 }, /* rear */
6978 { 0x17, 0x01016011 }, /* clfe */
6979 { }
6980};
6981
6982static const struct alc_pincfg *alc882_pin_fixes[] = {
6983 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6984};
6985
6986static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6987 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6988 {}
6989};
6990
df694daa
KY
6991/*
6992 * BIOS auto configuration
6993 */
6994static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6995 hda_nid_t nid, int pin_type,
6996 int dac_idx)
6997{
6998 /* set as output */
6999 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7000 int idx;
7001
f6c7e546 7002 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7003 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7004 idx = 4;
7005 else
7006 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
7007 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7008
7009}
7010
7011static void alc882_auto_init_multi_out(struct hda_codec *codec)
7012{
7013 struct alc_spec *spec = codec->spec;
7014 int i;
7015
bc9f98a9 7016 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 7017 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7018 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7019 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 7020 if (nid)
baba8ee9 7021 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7022 i);
df694daa
KY
7023 }
7024}
7025
7026static void alc882_auto_init_hp_out(struct hda_codec *codec)
7027{
7028 struct alc_spec *spec = codec->spec;
7029 hda_nid_t pin;
7030
eb06ed8f 7031 pin = spec->autocfg.hp_pins[0];
df694daa 7032 if (pin) /* connect to front */
f12ab1e0
TI
7033 /* use dac 0 */
7034 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
7035 pin = spec->autocfg.speaker_pins[0];
7036 if (pin)
7037 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
7038}
7039
7040#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7041#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7042
7043static void alc882_auto_init_analog_input(struct hda_codec *codec)
7044{
7045 struct alc_spec *spec = codec->spec;
7046 int i;
7047
7048 for (i = 0; i < AUTO_PIN_LAST; i++) {
7049 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
7050 if (!nid)
7051 continue;
23f0c048 7052 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7194cae6
TI
7053 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7054 snd_hda_codec_write(codec, nid, 0,
7055 AC_VERB_SET_AMP_GAIN_MUTE,
7056 AMP_OUT_MUTE);
df694daa
KY
7057 }
7058}
7059
f511b01c
TI
7060static void alc882_auto_init_input_src(struct hda_codec *codec)
7061{
7062 struct alc_spec *spec = codec->spec;
f511b01c
TI
7063 int c;
7064
7065 for (c = 0; c < spec->num_adc_nids; c++) {
7066 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7067 hda_nid_t nid = spec->capsrc_nids[c];
b98b7b34
HRK
7068 unsigned int mux_idx;
7069 const struct hda_input_mux *imux;
f511b01c
TI
7070 int conns, mute, idx, item;
7071
7072 conns = snd_hda_get_connections(codec, nid, conn_list,
7073 ARRAY_SIZE(conn_list));
7074 if (conns < 0)
7075 continue;
b98b7b34
HRK
7076 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7077 imux = &spec->input_mux[mux_idx];
f511b01c
TI
7078 for (idx = 0; idx < conns; idx++) {
7079 /* if the current connection is the selected one,
7080 * unmute it as default - otherwise mute it
7081 */
7082 mute = AMP_IN_MUTE(idx);
7083 for (item = 0; item < imux->num_items; item++) {
7084 if (imux->items[item].index == idx) {
7085 if (spec->cur_mux[c] == item)
7086 mute = AMP_IN_UNMUTE(idx);
7087 break;
7088 }
7089 }
b98b7b34
HRK
7090 /* check if we have a selector or mixer
7091 * we could check for the widget type instead, but
7092 * just check for Amp-In presence (in case of mixer
7093 * without amp-in there is something wrong, this
7094 * function shouldn't be used or capsrc nid is wrong)
7095 */
7096 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7097 snd_hda_codec_write(codec, nid, 0,
7098 AC_VERB_SET_AMP_GAIN_MUTE,
7099 mute);
7100 else if (mute != AMP_IN_MUTE(idx))
7101 snd_hda_codec_write(codec, nid, 0,
7102 AC_VERB_SET_CONNECT_SEL,
7103 idx);
f511b01c
TI
7104 }
7105 }
7106}
7107
776e184e
TI
7108/* add mic boosts if needed */
7109static int alc_auto_add_mic_boost(struct hda_codec *codec)
7110{
7111 struct alc_spec *spec = codec->spec;
7112 int err;
7113 hda_nid_t nid;
7114
7115 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 7116 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7117 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7118 "Mic Boost",
7119 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7120 if (err < 0)
7121 return err;
7122 }
7123 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 7124 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7125 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7126 "Front Mic Boost",
7127 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7128 if (err < 0)
7129 return err;
7130 }
7131 return 0;
7132}
7133
df694daa
KY
7134/* almost identical with ALC880 parser... */
7135static int alc882_parse_auto_config(struct hda_codec *codec)
7136{
7137 struct alc_spec *spec = codec->spec;
7138 int err = alc880_parse_auto_config(codec);
7139
7140 if (err < 0)
7141 return err;
776e184e
TI
7142 else if (!err)
7143 return 0; /* no config found */
7144
7145 err = alc_auto_add_mic_boost(codec);
7146 if (err < 0)
7147 return err;
7148
7149 /* hack - override the init verbs */
7150 spec->init_verbs[0] = alc882_auto_init_verbs;
7151
7152 return 1; /* config found */
df694daa
KY
7153}
7154
ae6b813a
TI
7155/* additional initialization for auto-configuration model */
7156static void alc882_auto_init(struct hda_codec *codec)
df694daa 7157{
f6c7e546 7158 struct alc_spec *spec = codec->spec;
df694daa
KY
7159 alc882_auto_init_multi_out(codec);
7160 alc882_auto_init_hp_out(codec);
7161 alc882_auto_init_analog_input(codec);
f511b01c 7162 alc882_auto_init_input_src(codec);
f6c7e546 7163 if (spec->unsol_event)
7fb0d78f 7164 alc_inithook(codec);
df694daa
KY
7165}
7166
7943a8ab
TI
7167static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7168
df694daa
KY
7169static int patch_alc882(struct hda_codec *codec)
7170{
7171 struct alc_spec *spec;
7172 int err, board_config;
7173
7174 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7175 if (spec == NULL)
7176 return -ENOMEM;
7177
7178 codec->spec = spec;
7179
f5fcc13c
TI
7180 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7181 alc882_models,
7182 alc882_cfg_tbl);
df694daa
KY
7183
7184 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
7185 /* Pick up systems that don't supply PCI SSID */
7186 switch (codec->subsystem_id) {
7187 case 0x106b0c00: /* Mac Pro */
7188 board_config = ALC885_MACPRO;
7189 break;
c54728d8 7190 case 0x106b1000: /* iMac 24 */
f3911c5a 7191 case 0x106b2800: /* AppleTV */
3077e44c 7192 case 0x106b3e00: /* iMac 24 Aluminium */
c54728d8
NF
7193 board_config = ALC885_IMAC24;
7194 break;
2d466381 7195 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
c7e0757a 7196 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
9c95c43d 7197 case 0x106b00a4: /* MacbookPro4,1 */
87350ad0 7198 case 0x106b2c00: /* Macbook Pro rev3 */
c7e0757a 7199 case 0x106b3600: /* Macbook 3.1 */
2a88464c 7200 case 0x106b3800: /* MacbookPro4,1 - latter revision */
87350ad0
TI
7201 board_config = ALC885_MBP3;
7202 break;
081d17c4 7203 default:
7943a8ab 7204 /* ALC889A is handled better as ALC888-compatible */
669faba2
CM
7205 if (codec->revision_id == 0x100101 ||
7206 codec->revision_id == 0x100103) {
7943a8ab
TI
7207 alc_free(codec);
7208 return patch_alc883(codec);
7209 }
081d17c4
TD
7210 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7211 "trying auto-probe from BIOS...\n");
7212 board_config = ALC882_AUTO;
7213 }
df694daa
KY
7214 }
7215
f95474ec
TI
7216 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7217
df694daa
KY
7218 if (board_config == ALC882_AUTO) {
7219 /* automatic parse from the BIOS config */
7220 err = alc882_parse_auto_config(codec);
7221 if (err < 0) {
7222 alc_free(codec);
7223 return err;
f12ab1e0 7224 } else if (!err) {
9c7f852e
TI
7225 printk(KERN_INFO
7226 "hda_codec: Cannot set up configuration "
7227 "from BIOS. Using base mode...\n");
df694daa
KY
7228 board_config = ALC882_3ST_DIG;
7229 }
7230 }
7231
680cd536
KK
7232 err = snd_hda_attach_beep_device(codec, 0x1);
7233 if (err < 0) {
7234 alc_free(codec);
7235 return err;
7236 }
7237
df694daa
KY
7238 if (board_config != ALC882_AUTO)
7239 setup_preset(spec, &alc882_presets[board_config]);
1da177e4 7240
2f893286
KY
7241 if (codec->vendor_id == 0x10ec0885) {
7242 spec->stream_name_analog = "ALC885 Analog";
7243 spec->stream_name_digital = "ALC885 Digital";
7244 } else {
7245 spec->stream_name_analog = "ALC882 Analog";
7246 spec->stream_name_digital = "ALC882 Digital";
7247 }
7248
df694daa
KY
7249 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7250 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
7251 /* FIXME: setup DAC5 */
7252 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7253 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 7254
df694daa
KY
7255 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7256 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 7257
61b9b9b1 7258 spec->capture_style = CAPT_MIX; /* matrix-style capture */
f12ab1e0 7259 if (!spec->adc_nids && spec->input_mux) {
df694daa 7260 /* check whether NID 0x07 is valid */
4a471b7d 7261 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
7262 /* get type */
7263 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
7264 if (wcap != AC_WID_AUD_IN) {
7265 spec->adc_nids = alc882_adc_nids_alt;
7266 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 7267 spec->capsrc_nids = alc882_capsrc_nids_alt;
df694daa
KY
7268 } else {
7269 spec->adc_nids = alc882_adc_nids;
7270 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 7271 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
7272 }
7273 }
f9e336f6 7274 set_capture_mixer(spec);
45bdd1c1 7275 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 7276
2134ea4f
TI
7277 spec->vmaster_nid = 0x0c;
7278
1da177e4 7279 codec->patch_ops = alc_patch_ops;
df694daa 7280 if (board_config == ALC882_AUTO)
ae6b813a 7281 spec->init_hook = alc882_auto_init;
cb53c626
TI
7282#ifdef CONFIG_SND_HDA_POWER_SAVE
7283 if (!spec->loopback.amplist)
7284 spec->loopback.amplist = alc882_loopbacks;
7285#endif
daead538 7286 codec->proc_widget_hook = print_realtek_coef;
df694daa
KY
7287
7288 return 0;
7289}
7290
7291/*
9c7f852e
TI
7292 * ALC883 support
7293 *
7294 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7295 * configuration. Each pin widget can choose any input DACs and a mixer.
7296 * Each ADC is connected from a mixer of all inputs. This makes possible
7297 * 6-channel independent captures.
7298 *
7299 * In addition, an independent DAC for the multi-playback (not used in this
7300 * driver yet).
df694daa 7301 */
9c7f852e
TI
7302#define ALC883_DIGOUT_NID 0x06
7303#define ALC883_DIGIN_NID 0x0a
df694daa 7304
3ab90935
WF
7305#define ALC1200_DIGOUT_NID 0x10
7306
9c7f852e
TI
7307static hda_nid_t alc883_dac_nids[4] = {
7308 /* front, rear, clfe, rear_surr */
f32a19e3 7309 0x02, 0x03, 0x04, 0x05
9c7f852e 7310};
df694daa 7311
9c7f852e
TI
7312static hda_nid_t alc883_adc_nids[2] = {
7313 /* ADC1-2 */
7314 0x08, 0x09,
7315};
f12ab1e0 7316
f9e336f6
TI
7317static hda_nid_t alc883_adc_nids_alt[1] = {
7318 /* ADC1 */
7319 0x08,
7320};
7321
5b2d1eca
VP
7322static hda_nid_t alc883_adc_nids_rev[2] = {
7323 /* ADC2-1 */
7324 0x09, 0x08
7325};
7326
61b9b9b1
HRK
7327#define alc889_adc_nids alc880_adc_nids
7328
e1406348
TI
7329static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7330
5b2d1eca
VP
7331static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7332
61b9b9b1
HRK
7333#define alc889_capsrc_nids alc882_capsrc_nids
7334
9c7f852e
TI
7335/* input MUX */
7336/* FIXME: should be a matrix-type input source selection */
df694daa 7337
9c7f852e
TI
7338static struct hda_input_mux alc883_capture_source = {
7339 .num_items = 4,
7340 .items = {
7341 { "Mic", 0x0 },
7342 { "Front Mic", 0x1 },
7343 { "Line", 0x2 },
7344 { "CD", 0x4 },
7345 },
7346};
bc9f98a9 7347
17bba1b7
J
7348static struct hda_input_mux alc883_3stack_6ch_intel = {
7349 .num_items = 4,
7350 .items = {
7351 { "Mic", 0x1 },
7352 { "Front Mic", 0x0 },
7353 { "Line", 0x2 },
7354 { "CD", 0x4 },
7355 },
7356};
7357
bc9f98a9
KY
7358static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7359 .num_items = 2,
7360 .items = {
7361 { "Mic", 0x1 },
7362 { "Line", 0x2 },
7363 },
7364};
7365
272a527c
KY
7366static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7367 .num_items = 4,
7368 .items = {
7369 { "Mic", 0x0 },
7370 { "iMic", 0x1 },
7371 { "Line", 0x2 },
7372 { "CD", 0x4 },
7373 },
7374};
7375
fb97dc67
J
7376static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7377 .num_items = 2,
7378 .items = {
7379 { "Mic", 0x0 },
7380 { "Int Mic", 0x1 },
7381 },
7382};
7383
e2757d5e
KY
7384static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7385 .num_items = 3,
7386 .items = {
7387 { "Mic", 0x0 },
7388 { "Front Mic", 0x1 },
7389 { "Line", 0x4 },
7390 },
7391};
7392
7393static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7394 .num_items = 2,
7395 .items = {
7396 { "Mic", 0x0 },
7397 { "Line", 0x2 },
7398 },
7399};
7400
9c7f852e
TI
7401/*
7402 * 2ch mode
7403 */
7404static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7405 { 2, NULL }
7406};
7407
7408/*
7409 * 2ch mode
7410 */
7411static struct hda_verb alc883_3ST_ch2_init[] = {
7412 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7413 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7414 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7415 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7416 { } /* end */
7417};
7418
b201131c
TD
7419/*
7420 * 4ch mode
7421 */
7422static struct hda_verb alc883_3ST_ch4_init[] = {
7423 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7424 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7425 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7427 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7428 { } /* end */
7429};
7430
9c7f852e
TI
7431/*
7432 * 6ch mode
7433 */
7434static struct hda_verb alc883_3ST_ch6_init[] = {
7435 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7436 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7437 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7438 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7439 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7440 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7441 { } /* end */
7442};
7443
b201131c 7444static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 7445 { 2, alc883_3ST_ch2_init },
b201131c 7446 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
7447 { 6, alc883_3ST_ch6_init },
7448};
7449
17bba1b7
J
7450/*
7451 * 2ch mode
7452 */
7453static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7454 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7455 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7458 { } /* end */
7459};
7460
7461/*
7462 * 4ch mode
7463 */
7464static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7465 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7466 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7469 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7470 { } /* end */
7471};
7472
7473/*
7474 * 6ch mode
7475 */
7476static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7477 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7478 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7479 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7480 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7481 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7482 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7483 { } /* end */
7484};
7485
7486static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7487 { 2, alc883_3ST_ch2_intel_init },
7488 { 4, alc883_3ST_ch4_intel_init },
7489 { 6, alc883_3ST_ch6_intel_init },
7490};
7491
9c7f852e
TI
7492/*
7493 * 6ch mode
7494 */
7495static struct hda_verb alc883_sixstack_ch6_init[] = {
7496 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7497 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7498 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7499 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7500 { } /* end */
7501};
7502
7503/*
7504 * 8ch mode
7505 */
7506static struct hda_verb alc883_sixstack_ch8_init[] = {
7507 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7508 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7509 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7510 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7511 { } /* end */
7512};
7513
7514static struct hda_channel_mode alc883_sixstack_modes[2] = {
7515 { 6, alc883_sixstack_ch6_init },
7516 { 8, alc883_sixstack_ch8_init },
7517};
7518
b373bdeb
AN
7519static struct hda_verb alc883_medion_eapd_verbs[] = {
7520 /* eanable EAPD on medion laptop */
7521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7522 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7523 { }
7524};
7525
9c7f852e
TI
7526/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7527 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7528 */
7529
7530static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 7531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
7532 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7533 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7534 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7535 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7536 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7537 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7538 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7539 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7540 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
7542 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7543 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7544 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7545 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7547 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 7548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 7549 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7550 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
df694daa 7552 { } /* end */
834be88d
TI
7553};
7554
a8848bd6
AS
7555static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7556 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7557 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7558 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7559 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7560 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7561 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7564 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7566 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7567 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7568 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
7569 { } /* end */
7570};
7571
0c4cc443 7572static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7574 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7576 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7577 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7578 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7580 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7581 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7582 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
7583 { } /* end */
7584};
7585
fb97dc67
J
7586static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7588 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7590 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7594 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7596 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
7597 { } /* end */
7598};
7599
9c7f852e
TI
7600static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7601 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7602 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7609 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7611 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7612 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7613 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7614 { } /* end */
7615};
df694daa 7616
9c7f852e
TI
7617static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7618 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7619 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7620 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7621 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7622 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7623 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7624 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7625 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7632 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7635 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7637 { } /* end */
7638};
7639
17bba1b7
J
7640static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7641 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7642 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7643 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7644 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7645 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7646 HDA_OUTPUT),
7647 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7648 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7649 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7656 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7659 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7660 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
7661 { } /* end */
7662};
7663
d1d985f0 7664static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7666 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7667 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7668 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7669 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7671 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7672 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7673 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7674 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7675 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7679 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7681 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7682 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 7683 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
7684 { } /* end */
7685};
7686
ccc656ce
KY
7687static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7688 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7690 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7691 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7692 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7693 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7694 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7695 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7696 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7697 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7698 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7700 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7702 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 7704 { } /* end */
f12ab1e0 7705};
ccc656ce
KY
7706
7707static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7708 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7710 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7711 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7712 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7716 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7717 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7718 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 7719 { } /* end */
f12ab1e0 7720};
ccc656ce 7721
bc9f98a9
KY
7722static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7723 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7724 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7725 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7726 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7729 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 7731 { } /* end */
f12ab1e0 7732};
bc9f98a9 7733
272a527c
KY
7734static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7735 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7736 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7738 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7739 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7742 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7743 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
7744 { } /* end */
7745};
7746
7747static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7748 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7750 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7751 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7752 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7755 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7756 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 7757 { } /* end */
ea1fb29a 7758};
272a527c 7759
2880a867 7760static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7761 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7762 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7767 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 7769 { } /* end */
d1a991a6 7770};
2880a867 7771
e2757d5e
KY
7772static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7773 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7774 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7776 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7777 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7778 0x0d, 1, 0x0, HDA_OUTPUT),
7779 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7780 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7781 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7782 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7783 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7785 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7786 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7787 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7788 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7789 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7791 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7794 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7795 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
7796 { } /* end */
7797};
7798
7799static struct hda_bind_ctls alc883_bind_cap_vol = {
7800 .ops = &snd_hda_bind_vol,
7801 .values = {
7802 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7803 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7804 0
7805 },
7806};
7807
7808static struct hda_bind_ctls alc883_bind_cap_switch = {
7809 .ops = &snd_hda_bind_sw,
7810 .values = {
7811 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7812 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7813 0
7814 },
7815};
7816
7817static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f9e336f6
TI
7826 { } /* end */
7827};
7828
7829static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
e2757d5e
KY
7830 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7831 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7832 {
7833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7834 /* .name = "Capture Source", */
7835 .name = "Input Source",
7836 .count = 1,
54cbc9ab
TI
7837 .info = alc_mux_enum_info,
7838 .get = alc_mux_enum_get,
7839 .put = alc_mux_enum_put,
e2757d5e
KY
7840 },
7841 { } /* end */
7842};
7843
9c7f852e
TI
7844static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7845 {
7846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7847 .name = "Channel Mode",
7848 .info = alc_ch_mode_info,
7849 .get = alc_ch_mode_get,
7850 .put = alc_ch_mode_put,
7851 },
7852 { } /* end */
7853};
7854
7855static struct hda_verb alc883_init_verbs[] = {
7856 /* ADC1: mute amp left and right */
e2757d5e 7857 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
df694daa 7858 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7859 /* ADC2: mute amp left and right */
7860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7862 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7866 /* Rear mixer */
7867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7869 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7870 /* CLFE mixer */
7871 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7873 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7874 /* Side mixer */
7875 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7876 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7877 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7878
cb53c626
TI
7879 /* mute analog input loopbacks */
7880 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7885
9c7f852e
TI
7886 /* Front Pin: output 0 (0x0c) */
7887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7890 /* Rear Pin: output 1 (0x0d) */
7891 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7893 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7894 /* CLFE Pin: output 2 (0x0e) */
7895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7897 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7898 /* Side Pin: output 3 (0x0f) */
7899 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7900 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7901 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7902 /* Mic (rear) pin: input vref at 80% */
7903 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7904 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7905 /* Front Mic pin: input vref at 80% */
7906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7908 /* Line In pin: input */
7909 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7910 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7911 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7912 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7913 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7914 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7915 /* CD pin widget for input */
7916 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7917
7918 /* FIXME: use matrix-type input source selection */
7919 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7920 /* Input mixer2 */
7921 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7925 /* Input mixer3 */
7926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7930 { }
7931};
7932
a8848bd6
AS
7933/* toggle speaker-output according to the hp-jack state */
7934static void alc883_mitac_hp_automute(struct hda_codec *codec)
7935{
7936 unsigned int present;
7937
7938 present = snd_hda_codec_read(codec, 0x15, 0,
7939 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7940 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7941 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7942 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7943 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7944}
7945
7946/* auto-toggle front mic */
7947/*
7948static void alc883_mitac_mic_automute(struct hda_codec *codec)
7949{
7950 unsigned int present;
7951 unsigned char bits;
7952
7953 present = snd_hda_codec_read(codec, 0x18, 0,
7954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7955 bits = present ? HDA_AMP_MUTE : 0;
7956 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7957}
7958*/
7959
7960static void alc883_mitac_automute(struct hda_codec *codec)
7961{
7962 alc883_mitac_hp_automute(codec);
7963 /* alc883_mitac_mic_automute(codec); */
7964}
7965
7966static void alc883_mitac_unsol_event(struct hda_codec *codec,
7967 unsigned int res)
7968{
7969 switch (res >> 26) {
7970 case ALC880_HP_EVENT:
7971 alc883_mitac_hp_automute(codec);
7972 break;
7973 case ALC880_MIC_EVENT:
7974 /* alc883_mitac_mic_automute(codec); */
7975 break;
7976 }
7977}
7978
7979static struct hda_verb alc883_mitac_verbs[] = {
7980 /* HP */
7981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7983 /* Subwoofer */
7984 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7985 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7986
7987 /* enable unsolicited event */
7988 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7989 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7990
7991 { } /* end */
7992};
7993
0c4cc443 7994static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
7995 /* HP */
7996 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7998 /* Int speaker */
7999 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8001
8002 /* enable unsolicited event */
8003 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8005
8006 { } /* end */
8007};
8008
fb97dc67
J
8009static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8010 /* HP */
8011 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8012 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8013 /* Subwoofer */
8014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8016
8017 /* enable unsolicited event */
8018 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8019
8020 { } /* end */
8021};
8022
ccc656ce
KY
8023static struct hda_verb alc883_tagra_verbs[] = {
8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8026
8027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8029
ccc656ce
KY
8030 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8031 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8032 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8033
8034 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
8035 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8036 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8037 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
8038
8039 { } /* end */
8040};
8041
bc9f98a9
KY
8042static struct hda_verb alc883_lenovo_101e_verbs[] = {
8043 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8045 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8046 { } /* end */
8047};
8048
272a527c
KY
8049static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8050 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8051 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8052 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8054 { } /* end */
8055};
8056
8057static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8061 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8062 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8063 { } /* end */
8064};
8065
189609ae
KY
8066static struct hda_verb alc883_haier_w66_verbs[] = {
8067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8069
8070 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8071
8072 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8074 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8075 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8076 { } /* end */
8077};
8078
e2757d5e
KY
8079static struct hda_verb alc888_lenovo_sky_verbs[] = {
8080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8082 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8083 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8086 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8087 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8088 { } /* end */
8089};
8090
8718b700
HRK
8091static struct hda_verb alc888_6st_dell_verbs[] = {
8092 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8093 { }
8094};
8095
8096static void alc888_3st_hp_front_automute(struct hda_codec *codec)
8097{
8098 unsigned int present, bits;
8099
8100 present = snd_hda_codec_read(codec, 0x1b, 0,
8101 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8102 bits = present ? HDA_AMP_MUTE : 0;
8103 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8104 HDA_AMP_MUTE, bits);
8105 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8106 HDA_AMP_MUTE, bits);
8107 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
8108 HDA_AMP_MUTE, bits);
8109}
8110
8111static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
8112 unsigned int res)
8113{
8114 switch (res >> 26) {
8115 case ALC880_HP_EVENT:
8116 alc888_3st_hp_front_automute(codec);
8117 break;
8118 }
8119}
8120
4723c022 8121static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8122 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8123 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8124 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8125 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8126 { } /* end */
5795b9e6
CM
8127};
8128
3ea0d7cf
HRK
8129/*
8130 * 2ch mode
8131 */
4723c022 8132static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8133 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8134 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8135 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8137 { } /* end */
8341de60
CM
8138};
8139
3ea0d7cf
HRK
8140/*
8141 * 4ch mode
8142 */
8143static struct hda_verb alc888_3st_hp_4ch_init[] = {
8144 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8145 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8146 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8147 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8148 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8149 { } /* end */
8150};
8151
8152/*
8153 * 6ch mode
8154 */
4723c022 8155static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8156 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8157 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8158 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8159 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8160 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8161 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8162 { } /* end */
8341de60
CM
8163};
8164
3ea0d7cf 8165static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8166 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8167 { 4, alc888_3st_hp_4ch_init },
4723c022 8168 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8169};
8170
272a527c
KY
8171/* toggle front-jack and RCA according to the hp-jack state */
8172static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8173{
8174 unsigned int present;
ea1fb29a 8175
272a527c
KY
8176 present = snd_hda_codec_read(codec, 0x1b, 0,
8177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8178 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8179 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8180 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8181 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8182}
8183
8184/* toggle RCA according to the front-jack state */
8185static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8186{
8187 unsigned int present;
ea1fb29a 8188
272a527c
KY
8189 present = snd_hda_codec_read(codec, 0x14, 0,
8190 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8191 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8192 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8193}
47fd830a 8194
272a527c
KY
8195static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8196 unsigned int res)
8197{
8198 if ((res >> 26) == ALC880_HP_EVENT)
8199 alc888_lenovo_ms7195_front_automute(codec);
8200 if ((res >> 26) == ALC880_FRONT_EVENT)
8201 alc888_lenovo_ms7195_rca_automute(codec);
8202}
8203
8204static struct hda_verb alc883_medion_md2_verbs[] = {
8205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8207
8208 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8209
8210 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8211 { } /* end */
8212};
8213
8214/* toggle speaker-output according to the hp-jack state */
8215static void alc883_medion_md2_automute(struct hda_codec *codec)
8216{
8217 unsigned int present;
ea1fb29a 8218
272a527c
KY
8219 present = snd_hda_codec_read(codec, 0x14, 0,
8220 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8221 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8222 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8223}
8224
8225static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8226 unsigned int res)
8227{
8228 if ((res >> 26) == ALC880_HP_EVENT)
8229 alc883_medion_md2_automute(codec);
8230}
8231
ccc656ce
KY
8232/* toggle speaker-output according to the hp-jack state */
8233static void alc883_tagra_automute(struct hda_codec *codec)
8234{
8235 unsigned int present;
f12ab1e0 8236 unsigned char bits;
ccc656ce
KY
8237
8238 present = snd_hda_codec_read(codec, 0x14, 0,
8239 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8240 bits = present ? HDA_AMP_MUTE : 0;
8241 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8242 HDA_AMP_MUTE, bits);
82beb8fd
TI
8243 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8244 present ? 1 : 3);
ccc656ce
KY
8245}
8246
8247static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8248{
8249 if ((res >> 26) == ALC880_HP_EVENT)
8250 alc883_tagra_automute(codec);
8251}
8252
368c7a95 8253/* toggle speaker-output according to the hp-jack state */
0c4cc443 8254static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
368c7a95
J
8255{
8256 unsigned int present;
8257 unsigned char bits;
8258
8259 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8260 & AC_PINSENSE_PRESENCE;
8261 bits = present ? HDA_AMP_MUTE : 0;
8262 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8263 HDA_AMP_MUTE, bits);
8264}
8265
0c4cc443
HRK
8266static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8267{
8268 unsigned int present;
8269
8270 present = snd_hda_codec_read(codec, 0x18, 0,
8271 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8272 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8273 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8274}
8275
8276static void alc883_clevo_m720_automute(struct hda_codec *codec)
8277{
8278 alc883_clevo_m720_hp_automute(codec);
8279 alc883_clevo_m720_mic_automute(codec);
8280}
8281
8282static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8283 unsigned int res)
8284{
0c4cc443
HRK
8285 switch (res >> 26) {
8286 case ALC880_HP_EVENT:
8287 alc883_clevo_m720_hp_automute(codec);
8288 break;
8289 case ALC880_MIC_EVENT:
8290 alc883_clevo_m720_mic_automute(codec);
8291 break;
8292 }
368c7a95
J
8293}
8294
fb97dc67
J
8295/* toggle speaker-output according to the hp-jack state */
8296static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8297{
8298 unsigned int present;
8299 unsigned char bits;
8300
8301 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8302 & AC_PINSENSE_PRESENCE;
8303 bits = present ? HDA_AMP_MUTE : 0;
8304 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8305 HDA_AMP_MUTE, bits);
8306}
8307
8308static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8309 unsigned int res)
8310{
8311 if ((res >> 26) == ALC880_HP_EVENT)
8312 alc883_2ch_fujitsu_pi2515_automute(codec);
8313}
8314
189609ae
KY
8315static void alc883_haier_w66_automute(struct hda_codec *codec)
8316{
8317 unsigned int present;
8318 unsigned char bits;
8319
8320 present = snd_hda_codec_read(codec, 0x1b, 0,
8321 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8322 bits = present ? 0x80 : 0;
8323 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8324 0x80, bits);
8325}
8326
8327static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8328 unsigned int res)
8329{
8330 if ((res >> 26) == ALC880_HP_EVENT)
8331 alc883_haier_w66_automute(codec);
8332}
8333
bc9f98a9
KY
8334static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8335{
8336 unsigned int present;
f12ab1e0 8337 unsigned char bits;
bc9f98a9
KY
8338
8339 present = snd_hda_codec_read(codec, 0x14, 0,
8340 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8341 bits = present ? HDA_AMP_MUTE : 0;
8342 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8343 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8344}
8345
8346static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8347{
8348 unsigned int present;
f12ab1e0 8349 unsigned char bits;
bc9f98a9
KY
8350
8351 present = snd_hda_codec_read(codec, 0x1b, 0,
8352 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8353 bits = present ? HDA_AMP_MUTE : 0;
8354 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8355 HDA_AMP_MUTE, bits);
8356 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8357 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8358}
8359
8360static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8361 unsigned int res)
8362{
8363 if ((res >> 26) == ALC880_HP_EVENT)
8364 alc883_lenovo_101e_all_automute(codec);
8365 if ((res >> 26) == ALC880_FRONT_EVENT)
8366 alc883_lenovo_101e_ispeaker_automute(codec);
8367}
8368
676a9b53
TI
8369/* toggle speaker-output according to the hp-jack state */
8370static void alc883_acer_aspire_automute(struct hda_codec *codec)
8371{
8372 unsigned int present;
ea1fb29a 8373
676a9b53
TI
8374 present = snd_hda_codec_read(codec, 0x14, 0,
8375 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8376 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8377 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8378 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8379 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8380}
8381
8382static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8383 unsigned int res)
8384{
8385 if ((res >> 26) == ALC880_HP_EVENT)
8386 alc883_acer_aspire_automute(codec);
8387}
8388
d1a991a6
KY
8389static struct hda_verb alc883_acer_eapd_verbs[] = {
8390 /* HP Pin: output 0 (0x0c) */
8391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8394 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8396 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8397 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8398 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8399 /* eanable EAPD on medion laptop */
8400 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8401 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8402 /* enable unsolicited event */
8403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8404 { }
8405};
8406
5795b9e6
CM
8407static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8408{
8409 unsigned int present;
ea1fb29a 8410
5795b9e6
CM
8411 present = snd_hda_codec_read(codec, 0x1b, 0,
8412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8413 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8414 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8415 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8416 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8417 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8418 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8419 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8421}
8422
8423static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8424 unsigned int res)
8425{
8426 switch (res >> 26) {
8427 case ALC880_HP_EVENT:
939778ae 8428 /* printk(KERN_DEBUG "hp_event\n"); */
5795b9e6
CM
8429 alc888_6st_dell_front_automute(codec);
8430 break;
8431 }
8432}
8433
e2757d5e
KY
8434static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8435{
8436 unsigned int mute;
8437 unsigned int present;
8438
8439 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8440 present = snd_hda_codec_read(codec, 0x1b, 0,
8441 AC_VERB_GET_PIN_SENSE, 0);
8442 present = (present & 0x80000000) != 0;
8443 if (present) {
8444 /* mute internal speaker */
8445 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8446 HDA_AMP_MUTE, HDA_AMP_MUTE);
8447 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8448 HDA_AMP_MUTE, HDA_AMP_MUTE);
8449 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8450 HDA_AMP_MUTE, HDA_AMP_MUTE);
8451 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8452 HDA_AMP_MUTE, HDA_AMP_MUTE);
8453 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8454 HDA_AMP_MUTE, HDA_AMP_MUTE);
8455 } else {
8456 /* unmute internal speaker if necessary */
8457 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8459 HDA_AMP_MUTE, mute);
8460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8461 HDA_AMP_MUTE, mute);
8462 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8463 HDA_AMP_MUTE, mute);
8464 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8465 HDA_AMP_MUTE, mute);
8466 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8467 HDA_AMP_MUTE, mute);
8468 }
8469}
8470
8471static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8472 unsigned int res)
8473{
8474 if ((res >> 26) == ALC880_HP_EVENT)
8475 alc888_lenovo_sky_front_automute(codec);
8476}
8477
9c7f852e
TI
8478/*
8479 * generic initialization of ADC, input mixers and output mixers
8480 */
8481static struct hda_verb alc883_auto_init_verbs[] = {
8482 /*
8483 * Unmute ADC0-2 and set the default input to mic-in
8484 */
8485 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8487 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8489
cb53c626 8490 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8491 * mixer widget
f12ab1e0
TI
8492 * Note: PASD motherboards uses the Line In 2 as the input for
8493 * front panel mic (mic 2)
9c7f852e
TI
8494 */
8495 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8501
8502 /*
8503 * Set up output mixers (0x0c - 0x0f)
8504 */
8505 /* set vol=0 to output mixers */
8506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510 /* set up input amps for analog loopback */
8511 /* Amp Indices: DAC = 0, mixer = 1 */
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8520 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8522
8523 /* FIXME: use matrix-type input source selection */
8524 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8525 /* Input mixer1 */
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8529 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
8530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8531 /* Input mixer2 */
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8535 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 8536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
8537
8538 { }
8539};
8540
e2757d5e
KY
8541static struct hda_verb alc888_asus_m90v_verbs[] = {
8542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8545 /* enable unsolicited event */
8546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8547 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8548 { } /* end */
8549};
8550
8551static void alc883_nb_mic_automute(struct hda_codec *codec)
8552{
8553 unsigned int present;
8554
8555 present = snd_hda_codec_read(codec, 0x18, 0,
8556 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8557 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8558 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8559 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8560 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8561}
8562
8563static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8564{
8565 unsigned int present;
8566 unsigned char bits;
8567
8568 present = snd_hda_codec_read(codec, 0x1b, 0,
8569 AC_VERB_GET_PIN_SENSE, 0)
8570 & AC_PINSENSE_PRESENCE;
8571 bits = present ? 0 : PIN_OUT;
8572 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8573 bits);
8574 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8575 bits);
8576 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8577 bits);
8578}
8579
8580static void alc883_mode2_unsol_event(struct hda_codec *codec,
8581 unsigned int res)
8582{
8583 switch (res >> 26) {
8584 case ALC880_HP_EVENT:
8585 alc883_M90V_speaker_automute(codec);
8586 break;
8587 case ALC880_MIC_EVENT:
8588 alc883_nb_mic_automute(codec);
8589 break;
8590 }
8591}
8592
8593static void alc883_mode2_inithook(struct hda_codec *codec)
8594{
8595 alc883_M90V_speaker_automute(codec);
8596 alc883_nb_mic_automute(codec);
8597}
8598
8599static struct hda_verb alc888_asus_eee1601_verbs[] = {
8600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8601 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8605 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8606 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8607 /* enable unsolicited event */
8608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8609 { } /* end */
8610};
8611
8612static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8613{
8614 unsigned int present;
8615 unsigned char bits;
8616
8617 present = snd_hda_codec_read(codec, 0x14, 0,
8618 AC_VERB_GET_PIN_SENSE, 0)
8619 & AC_PINSENSE_PRESENCE;
8620 bits = present ? 0 : PIN_OUT;
8621 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8622 bits);
8623}
8624
8625static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8626 unsigned int res)
8627{
8628 switch (res >> 26) {
8629 case ALC880_HP_EVENT:
8630 alc883_eee1601_speaker_automute(codec);
8631 break;
8632 }
8633}
8634
8635static void alc883_eee1601_inithook(struct hda_codec *codec)
8636{
8637 alc883_eee1601_speaker_automute(codec);
8638}
8639
cb53c626
TI
8640#ifdef CONFIG_SND_HDA_POWER_SAVE
8641#define alc883_loopbacks alc880_loopbacks
8642#endif
8643
9c7f852e
TI
8644/* pcm configuration: identiacal with ALC880 */
8645#define alc883_pcm_analog_playback alc880_pcm_analog_playback
8646#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 8647#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
8648#define alc883_pcm_digital_playback alc880_pcm_digital_playback
8649#define alc883_pcm_digital_capture alc880_pcm_digital_capture
8650
8651/*
8652 * configuration and preset
8653 */
f5fcc13c
TI
8654static const char *alc883_models[ALC883_MODEL_LAST] = {
8655 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8656 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8657 [ALC883_3ST_6ch] = "3stack-6ch",
8658 [ALC883_6ST_DIG] = "6stack-dig",
8659 [ALC883_TARGA_DIG] = "targa-dig",
8660 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 8661 [ALC883_ACER] = "acer",
2880a867 8662 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 8663 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
f5fcc13c 8664 [ALC883_MEDION] = "medion",
272a527c 8665 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8666 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8667 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8668 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8669 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8670 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8671 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8672 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8673 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8674 [ALC883_MITAC] = "mitac",
0c4cc443 8675 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8676 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 8677 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 8678 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
3ab90935 8679 [ALC1200_ASUS_P5Q] = "asus-p5q",
f5fcc13c
TI
8680 [ALC883_AUTO] = "auto",
8681};
8682
8683static struct snd_pci_quirk alc883_cfg_tbl[] = {
8684 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741 8685 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 8686 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 8687 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
8688 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8689 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8690 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
8691 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8692 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd
LW
8693 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8694 ALC888_ACER_ASPIRE_4930G),
b3bdb30b 8695 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
94683507 8696 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
a8e4f9dd
LW
8697 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8698 ALC888_ACER_ASPIRE_4930G),
cc374c47
JJGS
8699 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8700 ALC888_ACER_ASPIRE_4930G),
dea0a509
TI
8701 /* default Acer */
8702 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
5795b9e6 8703 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 8704 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8705 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8706 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8707 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 8708 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 8709 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
a01c30cb 8710 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
ac3e3741 8711 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 8712 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 8713 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 8714 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
97ec710c 8715 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 8716 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
2de686d2 8717 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
8718 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8719 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8720 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8721 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 8722 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 8723 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8724 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8725 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 8726 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 8727 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8728 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8729 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8730 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8731 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8732 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8733 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8734 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8735 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8736 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8737 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
8738 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8739 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8740 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 8741 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 8742 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8743 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8744 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 8745 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8746 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8747 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8748 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
dea0a509 8749 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8750 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 8751 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 8752 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 8753 ALC883_FUJITSU_PI2515),
bfb53037 8754 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 8755 ALC888_FUJITSU_XA3530),
272a527c 8756 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8757 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8758 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8759 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8760 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8761 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 8762 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 8763 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8764 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
17bba1b7
J
8765 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8766 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 8767 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
4b558991 8768 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
ac3e3741 8769 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
8770 {}
8771};
8772
f3cd3f5d
WF
8773static hda_nid_t alc883_slave_dig_outs[] = {
8774 ALC1200_DIGOUT_NID, 0,
8775};
8776
b25c9da1
WF
8777static hda_nid_t alc1200_slave_dig_outs[] = {
8778 ALC883_DIGOUT_NID, 0,
8779};
8780
9c7f852e
TI
8781static struct alc_config_preset alc883_presets[] = {
8782 [ALC883_3ST_2ch_DIG] = {
8783 .mixers = { alc883_3ST_2ch_mixer },
8784 .init_verbs = { alc883_init_verbs },
8785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8786 .dac_nids = alc883_dac_nids,
8787 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8788 .dig_in_nid = ALC883_DIGIN_NID,
8789 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8790 .channel_mode = alc883_3ST_2ch_modes,
8791 .input_mux = &alc883_capture_source,
8792 },
8793 [ALC883_3ST_6ch_DIG] = {
8794 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8795 .init_verbs = { alc883_init_verbs },
8796 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8797 .dac_nids = alc883_dac_nids,
8798 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8799 .dig_in_nid = ALC883_DIGIN_NID,
8800 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8801 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8802 .need_dac_fix = 1,
9c7f852e 8803 .input_mux = &alc883_capture_source,
f12ab1e0 8804 },
9c7f852e
TI
8805 [ALC883_3ST_6ch] = {
8806 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8807 .init_verbs = { alc883_init_verbs },
8808 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8809 .dac_nids = alc883_dac_nids,
9c7f852e
TI
8810 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8811 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8812 .need_dac_fix = 1,
9c7f852e 8813 .input_mux = &alc883_capture_source,
f12ab1e0 8814 },
17bba1b7
J
8815 [ALC883_3ST_6ch_INTEL] = {
8816 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8817 .init_verbs = { alc883_init_verbs },
8818 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8819 .dac_nids = alc883_dac_nids,
8820 .dig_out_nid = ALC883_DIGOUT_NID,
8821 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 8822 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
8823 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8824 .channel_mode = alc883_3ST_6ch_intel_modes,
8825 .need_dac_fix = 1,
8826 .input_mux = &alc883_3stack_6ch_intel,
8827 },
9c7f852e
TI
8828 [ALC883_6ST_DIG] = {
8829 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8830 .init_verbs = { alc883_init_verbs },
8831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8832 .dac_nids = alc883_dac_nids,
8833 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8834 .dig_in_nid = ALC883_DIGIN_NID,
8835 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8836 .channel_mode = alc883_sixstack_modes,
8837 .input_mux = &alc883_capture_source,
8838 },
ccc656ce
KY
8839 [ALC883_TARGA_DIG] = {
8840 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8841 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8843 .dac_nids = alc883_dac_nids,
8844 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8845 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8846 .channel_mode = alc883_3ST_6ch_modes,
8847 .need_dac_fix = 1,
8848 .input_mux = &alc883_capture_source,
8849 .unsol_event = alc883_tagra_unsol_event,
8850 .init_hook = alc883_tagra_automute,
8851 },
8852 [ALC883_TARGA_2ch_DIG] = {
8853 .mixers = { alc883_tagra_2ch_mixer},
8854 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8855 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8856 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8857 .adc_nids = alc883_adc_nids_alt,
8858 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
ccc656ce 8859 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8861 .channel_mode = alc883_3ST_2ch_modes,
8862 .input_mux = &alc883_capture_source,
8863 .unsol_event = alc883_tagra_unsol_event,
8864 .init_hook = alc883_tagra_automute,
8865 },
bab282b9 8866 [ALC883_ACER] = {
676a9b53 8867 .mixers = { alc883_base_mixer },
bab282b9
VA
8868 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8869 * and the headphone jack. Turn this on and rely on the
8870 * standard mute methods whenever the user wants to turn
8871 * these outputs off.
8872 */
8873 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8874 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8875 .dac_nids = alc883_dac_nids,
bab282b9
VA
8876 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8877 .channel_mode = alc883_3ST_2ch_modes,
8878 .input_mux = &alc883_capture_source,
8879 },
2880a867 8880 [ALC883_ACER_ASPIRE] = {
676a9b53 8881 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 8882 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
8883 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8884 .dac_nids = alc883_dac_nids,
8885 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
8886 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8887 .channel_mode = alc883_3ST_2ch_modes,
8888 .input_mux = &alc883_capture_source,
676a9b53
TI
8889 .unsol_event = alc883_acer_aspire_unsol_event,
8890 .init_hook = alc883_acer_aspire_automute,
d1a991a6 8891 },
5b2d1eca 8892 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 8893 .mixers = { alc888_base_mixer,
5b2d1eca
VP
8894 alc883_chmode_mixer },
8895 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8896 alc888_acer_aspire_4930g_verbs },
8897 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8898 .dac_nids = alc883_dac_nids,
8899 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8900 .adc_nids = alc883_adc_nids_rev,
8901 .capsrc_nids = alc883_capsrc_nids_rev,
8902 .dig_out_nid = ALC883_DIGOUT_NID,
8903 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8904 .channel_mode = alc883_3ST_6ch_modes,
8905 .need_dac_fix = 1,
8906 .num_mux_defs =
ef8ef5fb
VP
8907 ARRAY_SIZE(alc888_2_capture_sources),
8908 .input_mux = alc888_2_capture_sources,
5b2d1eca
VP
8909 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8910 .init_hook = alc888_acer_aspire_4930g_automute,
8911 },
c07584c8
TD
8912 [ALC883_MEDION] = {
8913 .mixers = { alc883_fivestack_mixer,
8914 alc883_chmode_mixer },
8915 .init_verbs = { alc883_init_verbs,
b373bdeb 8916 alc883_medion_eapd_verbs },
c07584c8
TD
8917 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8918 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8919 .adc_nids = alc883_adc_nids_alt,
8920 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
c07584c8
TD
8921 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8922 .channel_mode = alc883_sixstack_modes,
8923 .input_mux = &alc883_capture_source,
b373bdeb 8924 },
272a527c
KY
8925 [ALC883_MEDION_MD2] = {
8926 .mixers = { alc883_medion_md2_mixer},
8927 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8928 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8929 .dac_nids = alc883_dac_nids,
8930 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8931 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8932 .channel_mode = alc883_3ST_2ch_modes,
8933 .input_mux = &alc883_capture_source,
8934 .unsol_event = alc883_medion_md2_unsol_event,
8935 .init_hook = alc883_medion_md2_automute,
ea1fb29a 8936 },
b373bdeb 8937 [ALC883_LAPTOP_EAPD] = {
676a9b53 8938 .mixers = { alc883_base_mixer },
b373bdeb
AN
8939 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8940 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8941 .dac_nids = alc883_dac_nids,
b373bdeb
AN
8942 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8943 .channel_mode = alc883_3ST_2ch_modes,
8944 .input_mux = &alc883_capture_source,
8945 },
0c4cc443
HRK
8946 [ALC883_CLEVO_M720] = {
8947 .mixers = { alc883_clevo_m720_mixer },
8948 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
8949 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8950 .dac_nids = alc883_dac_nids,
8951 .dig_out_nid = ALC883_DIGOUT_NID,
8952 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8953 .channel_mode = alc883_3ST_2ch_modes,
8954 .input_mux = &alc883_capture_source,
0c4cc443
HRK
8955 .unsol_event = alc883_clevo_m720_unsol_event,
8956 .init_hook = alc883_clevo_m720_automute,
368c7a95 8957 },
bc9f98a9
KY
8958 [ALC883_LENOVO_101E_2ch] = {
8959 .mixers = { alc883_lenovo_101e_2ch_mixer},
8960 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8962 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8963 .adc_nids = alc883_adc_nids_alt,
8964 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
bc9f98a9
KY
8965 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8966 .channel_mode = alc883_3ST_2ch_modes,
8967 .input_mux = &alc883_lenovo_101e_capture_source,
8968 .unsol_event = alc883_lenovo_101e_unsol_event,
8969 .init_hook = alc883_lenovo_101e_all_automute,
8970 },
272a527c
KY
8971 [ALC883_LENOVO_NB0763] = {
8972 .mixers = { alc883_lenovo_nb0763_mixer },
8973 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8974 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8975 .dac_nids = alc883_dac_nids,
272a527c
KY
8976 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8977 .channel_mode = alc883_3ST_2ch_modes,
8978 .need_dac_fix = 1,
8979 .input_mux = &alc883_lenovo_nb0763_capture_source,
8980 .unsol_event = alc883_medion_md2_unsol_event,
8981 .init_hook = alc883_medion_md2_automute,
8982 },
8983 [ALC888_LENOVO_MS7195_DIG] = {
8984 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8985 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8986 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8987 .dac_nids = alc883_dac_nids,
8988 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8989 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8990 .channel_mode = alc883_3ST_6ch_modes,
8991 .need_dac_fix = 1,
8992 .input_mux = &alc883_capture_source,
8993 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8994 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
8995 },
8996 [ALC883_HAIER_W66] = {
8997 .mixers = { alc883_tagra_2ch_mixer},
8998 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8999 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9000 .dac_nids = alc883_dac_nids,
9001 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
9002 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9003 .channel_mode = alc883_3ST_2ch_modes,
9004 .input_mux = &alc883_capture_source,
9005 .unsol_event = alc883_haier_w66_unsol_event,
9006 .init_hook = alc883_haier_w66_automute,
eea6419e 9007 },
4723c022 9008 [ALC888_3ST_HP] = {
eea6419e 9009 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 9010 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
9011 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9012 .dac_nids = alc883_dac_nids,
4723c022
CM
9013 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9014 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
9015 .need_dac_fix = 1,
9016 .input_mux = &alc883_capture_source,
8718b700
HRK
9017 .unsol_event = alc888_3st_hp_unsol_event,
9018 .init_hook = alc888_3st_hp_front_automute,
8341de60 9019 },
5795b9e6 9020 [ALC888_6ST_DELL] = {
f24dbdc6 9021 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
9022 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9023 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9024 .dac_nids = alc883_dac_nids,
9025 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
9026 .dig_in_nid = ALC883_DIGIN_NID,
9027 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9028 .channel_mode = alc883_sixstack_modes,
9029 .input_mux = &alc883_capture_source,
9030 .unsol_event = alc888_6st_dell_unsol_event,
9031 .init_hook = alc888_6st_dell_front_automute,
9032 },
a8848bd6
AS
9033 [ALC883_MITAC] = {
9034 .mixers = { alc883_mitac_mixer },
9035 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9037 .dac_nids = alc883_dac_nids,
a8848bd6
AS
9038 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9039 .channel_mode = alc883_3ST_2ch_modes,
9040 .input_mux = &alc883_capture_source,
9041 .unsol_event = alc883_mitac_unsol_event,
9042 .init_hook = alc883_mitac_automute,
9043 },
fb97dc67
J
9044 [ALC883_FUJITSU_PI2515] = {
9045 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9046 .init_verbs = { alc883_init_verbs,
9047 alc883_2ch_fujitsu_pi2515_verbs},
9048 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9049 .dac_nids = alc883_dac_nids,
9050 .dig_out_nid = ALC883_DIGOUT_NID,
9051 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9052 .channel_mode = alc883_3ST_2ch_modes,
9053 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9054 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
9055 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
9056 },
ef8ef5fb
VP
9057 [ALC888_FUJITSU_XA3530] = {
9058 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9059 .init_verbs = { alc883_init_verbs,
9060 alc888_fujitsu_xa3530_verbs },
9061 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9062 .dac_nids = alc883_dac_nids,
9063 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9064 .adc_nids = alc883_adc_nids_rev,
9065 .capsrc_nids = alc883_capsrc_nids_rev,
9066 .dig_out_nid = ALC883_DIGOUT_NID,
9067 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9068 .channel_mode = alc888_4ST_8ch_intel_modes,
9069 .num_mux_defs =
9070 ARRAY_SIZE(alc888_2_capture_sources),
9071 .input_mux = alc888_2_capture_sources,
9072 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
9073 .init_hook = alc888_fujitsu_xa3530_automute,
9074 },
e2757d5e
KY
9075 [ALC888_LENOVO_SKY] = {
9076 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9077 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9078 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9079 .dac_nids = alc883_dac_nids,
9080 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
9081 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9082 .channel_mode = alc883_sixstack_modes,
9083 .need_dac_fix = 1,
9084 .input_mux = &alc883_lenovo_sky_capture_source,
9085 .unsol_event = alc883_lenovo_sky_unsol_event,
9086 .init_hook = alc888_lenovo_sky_front_automute,
9087 },
9088 [ALC888_ASUS_M90V] = {
9089 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9090 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9091 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9092 .dac_nids = alc883_dac_nids,
9093 .dig_out_nid = ALC883_DIGOUT_NID,
9094 .dig_in_nid = ALC883_DIGIN_NID,
9095 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9096 .channel_mode = alc883_3ST_6ch_modes,
9097 .need_dac_fix = 1,
9098 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9099 .unsol_event = alc883_mode2_unsol_event,
9100 .init_hook = alc883_mode2_inithook,
9101 },
9102 [ALC888_ASUS_EEE1601] = {
9103 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 9104 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
9105 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9106 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9107 .dac_nids = alc883_dac_nids,
9108 .dig_out_nid = ALC883_DIGOUT_NID,
9109 .dig_in_nid = ALC883_DIGIN_NID,
9110 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9111 .channel_mode = alc883_3ST_2ch_modes,
9112 .need_dac_fix = 1,
9113 .input_mux = &alc883_asus_eee1601_capture_source,
9114 .unsol_event = alc883_eee1601_unsol_event,
9115 .init_hook = alc883_eee1601_inithook,
9116 },
3ab90935
WF
9117 [ALC1200_ASUS_P5Q] = {
9118 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9119 .init_verbs = { alc883_init_verbs },
9120 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9121 .dac_nids = alc883_dac_nids,
9122 .dig_out_nid = ALC1200_DIGOUT_NID,
9123 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 9124 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
9125 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9126 .channel_mode = alc883_sixstack_modes,
9127 .input_mux = &alc883_capture_source,
9128 },
9c7f852e
TI
9129};
9130
9131
9132/*
9133 * BIOS auto configuration
9134 */
9135static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9136 hda_nid_t nid, int pin_type,
9137 int dac_idx)
9138{
9139 /* set as output */
9140 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
9141 int idx;
9142
f6c7e546 9143 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
9144 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9145 idx = 4;
9146 else
9147 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
9148 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9149
9150}
9151
9152static void alc883_auto_init_multi_out(struct hda_codec *codec)
9153{
9154 struct alc_spec *spec = codec->spec;
9155 int i;
9156
bc9f98a9 9157 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 9158 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 9159 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 9160 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 9161 if (nid)
baba8ee9 9162 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 9163 i);
9c7f852e
TI
9164 }
9165}
9166
9167static void alc883_auto_init_hp_out(struct hda_codec *codec)
9168{
9169 struct alc_spec *spec = codec->spec;
9170 hda_nid_t pin;
9171
eb06ed8f 9172 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
9173 if (pin) /* connect to front */
9174 /* use dac 0 */
9175 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
9176 pin = spec->autocfg.speaker_pins[0];
9177 if (pin)
9178 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
9179}
9180
9181#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9182#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9183
9184static void alc883_auto_init_analog_input(struct hda_codec *codec)
9185{
9186 struct alc_spec *spec = codec->spec;
9187 int i;
9188
9189 for (i = 0; i < AUTO_PIN_LAST; i++) {
9190 hda_nid_t nid = spec->autocfg.input_pins[i];
9191 if (alc883_is_input_pin(nid)) {
23f0c048 9192 alc_set_input_pin(codec, nid, i);
e82c025b
TI
9193 if (nid != ALC883_PIN_CD_NID &&
9194 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9c7f852e
TI
9195 snd_hda_codec_write(codec, nid, 0,
9196 AC_VERB_SET_AMP_GAIN_MUTE,
9197 AMP_OUT_MUTE);
9198 }
9199 }
9200}
9201
f511b01c
TI
9202#define alc883_auto_init_input_src alc882_auto_init_input_src
9203
9c7f852e
TI
9204/* almost identical with ALC880 parser... */
9205static int alc883_parse_auto_config(struct hda_codec *codec)
9206{
9207 struct alc_spec *spec = codec->spec;
9208 int err = alc880_parse_auto_config(codec);
61b9b9b1
HRK
9209 struct auto_pin_cfg *cfg = &spec->autocfg;
9210 int i;
9c7f852e
TI
9211
9212 if (err < 0)
9213 return err;
776e184e
TI
9214 else if (!err)
9215 return 0; /* no config found */
9216
9217 err = alc_auto_add_mic_boost(codec);
9218 if (err < 0)
9219 return err;
9220
9221 /* hack - override the init verbs */
9222 spec->init_verbs[0] = alc883_auto_init_verbs;
776e184e 9223
61b9b9b1
HRK
9224 /* setup input_mux for ALC889 */
9225 if (codec->vendor_id == 0x10ec0889) {
9226 /* digital-mic input pin is excluded in alc880_auto_create..()
9227 * because it's under 0x18
9228 */
9229 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9230 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9231 struct hda_input_mux *imux = &spec->private_imux[0];
9232 for (i = 1; i < 3; i++)
9233 memcpy(&spec->private_imux[i],
9234 &spec->private_imux[0],
9235 sizeof(spec->private_imux[0]));
9236 imux->items[imux->num_items].label = "Int DMic";
9237 imux->items[imux->num_items].index = 0x0b;
9238 imux->num_items++;
9239 spec->num_mux_defs = 3;
9240 spec->input_mux = spec->private_imux;
9241 }
9242 }
9243
776e184e 9244 return 1; /* config found */
9c7f852e
TI
9245}
9246
9247/* additional initialization for auto-configuration model */
9248static void alc883_auto_init(struct hda_codec *codec)
9249{
f6c7e546 9250 struct alc_spec *spec = codec->spec;
9c7f852e
TI
9251 alc883_auto_init_multi_out(codec);
9252 alc883_auto_init_hp_out(codec);
9253 alc883_auto_init_analog_input(codec);
f511b01c 9254 alc883_auto_init_input_src(codec);
f6c7e546 9255 if (spec->unsol_event)
7fb0d78f 9256 alc_inithook(codec);
9c7f852e
TI
9257}
9258
9259static int patch_alc883(struct hda_codec *codec)
9260{
9261 struct alc_spec *spec;
9262 int err, board_config;
9263
9264 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9265 if (spec == NULL)
9266 return -ENOMEM;
9267
9268 codec->spec = spec;
9269
2c3bf9ab
TI
9270 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9271
f5fcc13c
TI
9272 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9273 alc883_models,
9274 alc883_cfg_tbl);
9275 if (board_config < 0) {
9c7f852e
TI
9276 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9277 "trying auto-probe from BIOS...\n");
9278 board_config = ALC883_AUTO;
9279 }
9280
9281 if (board_config == ALC883_AUTO) {
9282 /* automatic parse from the BIOS config */
9283 err = alc883_parse_auto_config(codec);
9284 if (err < 0) {
9285 alc_free(codec);
9286 return err;
f12ab1e0 9287 } else if (!err) {
9c7f852e
TI
9288 printk(KERN_INFO
9289 "hda_codec: Cannot set up configuration "
9290 "from BIOS. Using base mode...\n");
9291 board_config = ALC883_3ST_2ch_DIG;
9292 }
9293 }
9294
680cd536
KK
9295 err = snd_hda_attach_beep_device(codec, 0x1);
9296 if (err < 0) {
9297 alc_free(codec);
9298 return err;
9299 }
9300
9c7f852e
TI
9301 if (board_config != ALC883_AUTO)
9302 setup_preset(spec, &alc883_presets[board_config]);
9303
2f893286
KY
9304 switch (codec->vendor_id) {
9305 case 0x10ec0888:
4442608d
KY
9306 if (codec->revision_id == 0x100101) {
9307 spec->stream_name_analog = "ALC1200 Analog";
9308 spec->stream_name_digital = "ALC1200 Digital";
9309 } else {
9310 spec->stream_name_analog = "ALC888 Analog";
9311 spec->stream_name_digital = "ALC888 Digital";
9312 }
61b9b9b1
HRK
9313 if (!spec->num_adc_nids) {
9314 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9315 spec->adc_nids = alc883_adc_nids;
9316 }
9317 if (!spec->capsrc_nids)
9318 spec->capsrc_nids = alc883_capsrc_nids;
9319 spec->capture_style = CAPT_MIX; /* matrix-style capture */
2f893286
KY
9320 break;
9321 case 0x10ec0889:
9322 spec->stream_name_analog = "ALC889 Analog";
9323 spec->stream_name_digital = "ALC889 Digital";
61b9b9b1
HRK
9324 if (!spec->num_adc_nids) {
9325 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9326 spec->adc_nids = alc889_adc_nids;
9327 }
9328 if (!spec->capsrc_nids)
9329 spec->capsrc_nids = alc889_capsrc_nids;
9330 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9331 capture */
2f893286
KY
9332 break;
9333 default:
9334 spec->stream_name_analog = "ALC883 Analog";
9335 spec->stream_name_digital = "ALC883 Digital";
61b9b9b1
HRK
9336 if (!spec->num_adc_nids) {
9337 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9338 spec->adc_nids = alc883_adc_nids;
9339 }
9340 if (!spec->capsrc_nids)
9341 spec->capsrc_nids = alc883_capsrc_nids;
9342 spec->capture_style = CAPT_MIX; /* matrix-style capture */
2f893286
KY
9343 break;
9344 }
9345
9c7f852e
TI
9346 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9347 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 9348 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e 9349
9c7f852e
TI
9350 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9351 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9352
f9e336f6
TI
9353 if (!spec->cap_mixer)
9354 set_capture_mixer(spec);
45bdd1c1 9355 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 9356
2134ea4f
TI
9357 spec->vmaster_nid = 0x0c;
9358
9c7f852e
TI
9359 codec->patch_ops = alc_patch_ops;
9360 if (board_config == ALC883_AUTO)
9361 spec->init_hook = alc883_auto_init;
f9423e7a 9362
cb53c626
TI
9363#ifdef CONFIG_SND_HDA_POWER_SAVE
9364 if (!spec->loopback.amplist)
9365 spec->loopback.amplist = alc883_loopbacks;
9366#endif
daead538 9367 codec->proc_widget_hook = print_realtek_coef;
9c7f852e
TI
9368
9369 return 0;
9370}
9371
9372/*
9373 * ALC262 support
9374 */
9375
9376#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9377#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9378
9379#define alc262_dac_nids alc260_dac_nids
9380#define alc262_adc_nids alc882_adc_nids
9381#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
9382#define alc262_capsrc_nids alc882_capsrc_nids
9383#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
9384
9385#define alc262_modes alc260_modes
9386#define alc262_capture_source alc882_capture_source
9387
4e555fe5
KY
9388static hda_nid_t alc262_dmic_adc_nids[1] = {
9389 /* ADC0 */
9390 0x09
9391};
9392
9393static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9394
9c7f852e
TI
9395static struct snd_kcontrol_new alc262_base_mixer[] = {
9396 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9397 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9398 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9399 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9401 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9405 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9406 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9408 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9409 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9410 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9411 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9412 { } /* end */
9413};
9414
ccc656ce
KY
9415static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9417 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9423 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9424 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
9425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9427 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce
KY
9428 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9430 { } /* end */
9431};
9432
ce875f07
TI
9433/* update HP, line and mono-out pins according to the master switch */
9434static void alc262_hp_master_update(struct hda_codec *codec)
9435{
9436 struct alc_spec *spec = codec->spec;
9437 int val = spec->master_sw;
9438
9439 /* HP & line-out */
9440 snd_hda_codec_write_cache(codec, 0x1b, 0,
9441 AC_VERB_SET_PIN_WIDGET_CONTROL,
9442 val ? PIN_HP : 0);
9443 snd_hda_codec_write_cache(codec, 0x15, 0,
9444 AC_VERB_SET_PIN_WIDGET_CONTROL,
9445 val ? PIN_HP : 0);
9446 /* mono (speaker) depending on the HP jack sense */
9447 val = val && !spec->jack_present;
9448 snd_hda_codec_write_cache(codec, 0x16, 0,
9449 AC_VERB_SET_PIN_WIDGET_CONTROL,
9450 val ? PIN_OUT : 0);
9451}
9452
9453static void alc262_hp_bpc_automute(struct hda_codec *codec)
9454{
9455 struct alc_spec *spec = codec->spec;
9456 unsigned int presence;
9457 presence = snd_hda_codec_read(codec, 0x1b, 0,
9458 AC_VERB_GET_PIN_SENSE, 0);
9459 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9460 alc262_hp_master_update(codec);
9461}
9462
9463static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9464{
9465 if ((res >> 26) != ALC880_HP_EVENT)
9466 return;
9467 alc262_hp_bpc_automute(codec);
9468}
9469
9470static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9471{
9472 struct alc_spec *spec = codec->spec;
9473 unsigned int presence;
9474 presence = snd_hda_codec_read(codec, 0x15, 0,
9475 AC_VERB_GET_PIN_SENSE, 0);
9476 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9477 alc262_hp_master_update(codec);
9478}
9479
9480static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9481 unsigned int res)
9482{
9483 if ((res >> 26) != ALC880_HP_EVENT)
9484 return;
9485 alc262_hp_wildwest_automute(codec);
9486}
9487
9488static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9489 struct snd_ctl_elem_value *ucontrol)
9490{
9491 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9492 struct alc_spec *spec = codec->spec;
9493 *ucontrol->value.integer.value = spec->master_sw;
9494 return 0;
9495}
9496
9497static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9498 struct snd_ctl_elem_value *ucontrol)
9499{
9500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9501 struct alc_spec *spec = codec->spec;
9502 int val = !!*ucontrol->value.integer.value;
9503
9504 if (val == spec->master_sw)
9505 return 0;
9506 spec->master_sw = val;
9507 alc262_hp_master_update(codec);
9508 return 1;
9509}
9510
9c7f852e 9511static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
9512 {
9513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9514 .name = "Master Playback Switch",
9515 .info = snd_ctl_boolean_mono_info,
9516 .get = alc262_hp_master_sw_get,
9517 .put = alc262_hp_master_sw_put,
9518 },
9c7f852e
TI
9519 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9520 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9522 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9523 HDA_OUTPUT),
9524 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9525 HDA_OUTPUT),
9c7f852e
TI
9526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9528 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9529 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9530 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9531 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9534 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9535 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
9536 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9537 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9538 { } /* end */
9539};
9540
cd7509a4 9541static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
9542 {
9543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9544 .name = "Master Playback Switch",
9545 .info = snd_ctl_boolean_mono_info,
9546 .get = alc262_hp_master_sw_get,
9547 .put = alc262_hp_master_sw_put,
9548 },
cd7509a4
KY
9549 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9550 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9551 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9552 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9553 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9554 HDA_OUTPUT),
9555 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9556 HDA_OUTPUT),
cd7509a4
KY
9557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9559 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9560 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9561 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9562 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9563 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
9564 { } /* end */
9565};
9566
9567static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9568 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9569 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9570 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9571 { } /* end */
9572};
9573
66d2a9d6
KY
9574/* mute/unmute internal speaker according to the hp jack and mute state */
9575static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9576{
9577 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
9578
9579 if (force || !spec->sense_updated) {
9580 unsigned int present;
9581 present = snd_hda_codec_read(codec, 0x15, 0,
9582 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 9583 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
9584 spec->sense_updated = 1;
9585 }
4bb26130
TI
9586 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9587 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
9588}
9589
9590static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9591 unsigned int res)
9592{
9593 if ((res >> 26) != ALC880_HP_EVENT)
9594 return;
9595 alc262_hp_t5735_automute(codec, 1);
9596}
9597
9598static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9599{
9600 alc262_hp_t5735_automute(codec, 1);
9601}
9602
9603static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9604 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9605 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9606 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9610 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9611 { } /* end */
9612};
9613
9614static struct hda_verb alc262_hp_t5735_verbs[] = {
9615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9617
9618 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9619 { }
9620};
9621
8c427226 9622static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9623 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9624 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9626 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9629 { } /* end */
9630};
9631
9632static struct hda_verb alc262_hp_rp5700_verbs[] = {
9633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9634 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9636 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9638 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9640 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9641 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9642 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9643 {}
9644};
9645
9646static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9647 .num_items = 1,
9648 .items = {
9649 { "Line", 0x1 },
9650 },
9651};
9652
0724ea2a
TI
9653/* bind hp and internal speaker mute (with plug check) */
9654static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9655 struct snd_ctl_elem_value *ucontrol)
9656{
9657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9658 long *valp = ucontrol->value.integer.value;
9659 int change;
9660
9661 /* change hp mute */
9662 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9663 HDA_AMP_MUTE,
9664 valp[0] ? 0 : HDA_AMP_MUTE);
9665 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9666 HDA_AMP_MUTE,
9667 valp[1] ? 0 : HDA_AMP_MUTE);
9668 if (change) {
9669 /* change speaker according to HP jack state */
9670 struct alc_spec *spec = codec->spec;
9671 unsigned int mute;
9672 if (spec->jack_present)
9673 mute = HDA_AMP_MUTE;
9674 else
9675 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9676 HDA_OUTPUT, 0);
9677 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9678 HDA_AMP_MUTE, mute);
9679 }
9680 return change;
9681}
5b31954e 9682
272a527c 9683static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
9684 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9685 {
9686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9687 .name = "Master Playback Switch",
9688 .info = snd_hda_mixer_amp_switch_info,
9689 .get = snd_hda_mixer_amp_switch_get,
9690 .put = alc262_sony_master_sw_put,
9691 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9692 },
272a527c
KY
9693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9697 { } /* end */
9698};
9699
83c34218
KY
9700static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9701 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9702 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9706 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9707 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9708 { } /* end */
9709};
272a527c 9710
ba340e82
TV
9711static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9712 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9713 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9714 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9715 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9716 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9717 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9718 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9719 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9721 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9722 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9723 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9724 { } /* end */
9725};
9726
9727static struct hda_verb alc262_tyan_verbs[] = {
9728 /* Headphone automute */
9729 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9730 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9732
9733 /* P11 AUX_IN, white 4-pin connector */
9734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9735 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9736 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9737 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9738
9739 {}
9740};
9741
9742/* unsolicited event for HP jack sensing */
9743static void alc262_tyan_automute(struct hda_codec *codec)
9744{
9745 unsigned int mute;
9746 unsigned int present;
9747
9748 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9749 present = snd_hda_codec_read(codec, 0x1b, 0,
9750 AC_VERB_GET_PIN_SENSE, 0);
9751 present = (present & 0x80000000) != 0;
9752 if (present) {
9753 /* mute line output on ATX panel */
9754 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9755 HDA_AMP_MUTE, HDA_AMP_MUTE);
9756 } else {
9757 /* unmute line output if necessary */
9758 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9759 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9760 HDA_AMP_MUTE, mute);
9761 }
9762}
9763
9764static void alc262_tyan_unsol_event(struct hda_codec *codec,
9765 unsigned int res)
9766{
9767 if ((res >> 26) != ALC880_HP_EVENT)
9768 return;
9769 alc262_tyan_automute(codec);
9770}
9771
9c7f852e
TI
9772#define alc262_capture_mixer alc882_capture_mixer
9773#define alc262_capture_alt_mixer alc882_capture_alt_mixer
9774
9775/*
9776 * generic initialization of ADC, input mixers and output mixers
9777 */
9778static struct hda_verb alc262_init_verbs[] = {
9779 /*
9780 * Unmute ADC0-2 and set the default input to mic-in
9781 */
9782 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9784 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9785 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9786 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9787 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9788
cb53c626 9789 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9790 * mixer widget
f12ab1e0
TI
9791 * Note: PASD motherboards uses the Line In 2 as the input for
9792 * front panel mic (mic 2)
9c7f852e
TI
9793 */
9794 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9799 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
9800
9801 /*
df694daa
KY
9802 * Set up output mixers (0x0c - 0x0e)
9803 */
9804 /* set vol=0 to output mixers */
9805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9808 /* set up input amps for analog loopback */
9809 /* Amp Indices: DAC = 0, mixer = 1 */
9810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9812 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9816
9817 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9818 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9822 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9823
9824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9827 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 9829
df694daa
KY
9830 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9831 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 9832
df694daa
KY
9833 /* FIXME: use matrix-type input source selection */
9834 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9835 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9840 /* Input mixer2 */
9841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9844 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9845 /* Input mixer3 */
9846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 9849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
9850
9851 { }
9852};
1da177e4 9853
4e555fe5
KY
9854static struct hda_verb alc262_eapd_verbs[] = {
9855 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9856 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9857 { }
9858};
9859
ccc656ce
KY
9860static struct hda_verb alc262_hippo_unsol_verbs[] = {
9861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9863 {}
9864};
9865
9866static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9868 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9869 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9870
9871 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9873 {}
9874};
9875
272a527c
KY
9876static struct hda_verb alc262_sony_unsol_verbs[] = {
9877 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9880
9881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 9883 {}
272a527c
KY
9884};
9885
4e555fe5
KY
9886static struct hda_input_mux alc262_dmic_capture_source = {
9887 .num_items = 2,
9888 .items = {
9889 { "Int DMic", 0x9 },
9890 { "Mic", 0x0 },
9891 },
9892};
9893
9894static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9895 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9896 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
9900 { } /* end */
9901};
9902
9903static struct hda_verb alc262_toshiba_s06_verbs[] = {
9904 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9907 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9908 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9910 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9911 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9912 {}
9913};
9914
9915static void alc262_dmic_automute(struct hda_codec *codec)
9916{
9917 unsigned int present;
9918
9919 present = snd_hda_codec_read(codec, 0x18, 0,
9920 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9921 snd_hda_codec_write(codec, 0x22, 0,
9922 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9923}
9924
9925/* toggle speaker-output according to the hp-jack state */
9926static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9927{
9928 unsigned int present;
9929 unsigned char bits;
9930
9931 present = snd_hda_codec_read(codec, 0x15, 0,
9932 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9933 bits = present ? 0 : PIN_OUT;
9934 snd_hda_codec_write(codec, 0x14, 0,
9935 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9936}
9937
9938
9939
9940/* unsolicited event for HP jack sensing */
9941static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9942 unsigned int res)
9943{
9944 if ((res >> 26) == ALC880_HP_EVENT)
9945 alc262_toshiba_s06_speaker_automute(codec);
9946 if ((res >> 26) == ALC880_MIC_EVENT)
9947 alc262_dmic_automute(codec);
9948
9949}
9950
9951static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9952{
9953 alc262_toshiba_s06_speaker_automute(codec);
9954 alc262_dmic_automute(codec);
9955}
9956
ccc656ce 9957/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 9958static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
9959{
9960 struct alc_spec *spec = codec->spec;
9961 unsigned int mute;
5b31954e 9962 unsigned int present;
ccc656ce 9963
5b31954e
TI
9964 /* need to execute and sync at first */
9965 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9966 present = snd_hda_codec_read(codec, 0x15, 0,
9967 AC_VERB_GET_PIN_SENSE, 0);
9968 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
9969 if (spec->jack_present) {
9970 /* mute internal speaker */
47fd830a
TI
9971 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9972 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9973 } else {
9974 /* unmute internal speaker if necessary */
9975 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
9976 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9977 HDA_AMP_MUTE, mute);
ccc656ce
KY
9978 }
9979}
9980
9981/* unsolicited event for HP jack sensing */
9982static void alc262_hippo_unsol_event(struct hda_codec *codec,
9983 unsigned int res)
9984{
9985 if ((res >> 26) != ALC880_HP_EVENT)
9986 return;
5b31954e 9987 alc262_hippo_automute(codec);
ccc656ce
KY
9988}
9989
5b31954e 9990static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 9991{
ccc656ce 9992 unsigned int mute;
5b31954e 9993 unsigned int present;
ccc656ce 9994
5b31954e
TI
9995 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9996 present = snd_hda_codec_read(codec, 0x1b, 0,
9997 AC_VERB_GET_PIN_SENSE, 0);
9998 present = (present & 0x80000000) != 0;
9999 if (present) {
ccc656ce 10000 /* mute internal speaker */
47fd830a
TI
10001 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10002 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
10003 } else {
10004 /* unmute internal speaker if necessary */
10005 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
10006 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10007 HDA_AMP_MUTE, mute);
ccc656ce
KY
10008 }
10009}
10010
10011/* unsolicited event for HP jack sensing */
10012static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10013 unsigned int res)
10014{
10015 if ((res >> 26) != ALC880_HP_EVENT)
10016 return;
5b31954e 10017 alc262_hippo1_automute(codec);
ccc656ce
KY
10018}
10019
e8f9ae2a
PT
10020/*
10021 * nec model
10022 * 0x15 = headphone
10023 * 0x16 = internal speaker
10024 * 0x18 = external mic
10025 */
10026
10027static struct snd_kcontrol_new alc262_nec_mixer[] = {
10028 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10029 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10030
10031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10033 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10034
10035 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10037 { } /* end */
10038};
10039
10040static struct hda_verb alc262_nec_verbs[] = {
10041 /* Unmute Speaker */
10042 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10043
10044 /* Headphone */
10045 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10047
10048 /* External mic to headphone */
10049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10050 /* External mic to speaker */
10051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10052 {}
10053};
10054
834be88d
TI
10055/*
10056 * fujitsu model
5d9fab2d
TV
10057 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10058 * 0x1b = port replicator headphone out
834be88d
TI
10059 */
10060
10061#define ALC_HP_EVENT 0x37
10062
10063static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10064 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
10066 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10067 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
10068 {}
10069};
10070
0e31daf7
J
10071static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10074 {}
10075};
10076
834be88d 10077static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 10078 .num_items = 3,
834be88d
TI
10079 .items = {
10080 { "Mic", 0x0 },
39d3ed38 10081 { "Int Mic", 0x1 },
834be88d
TI
10082 { "CD", 0x4 },
10083 },
10084};
10085
9c7f852e
TI
10086static struct hda_input_mux alc262_HP_capture_source = {
10087 .num_items = 5,
10088 .items = {
10089 { "Mic", 0x0 },
accbe498 10090 { "Front Mic", 0x1 },
9c7f852e
TI
10091 { "Line", 0x2 },
10092 { "CD", 0x4 },
10093 { "AUX IN", 0x6 },
10094 },
10095};
10096
accbe498 10097static struct hda_input_mux alc262_HP_D7000_capture_source = {
10098 .num_items = 4,
10099 .items = {
10100 { "Mic", 0x0 },
10101 { "Front Mic", 0x2 },
10102 { "Line", 0x1 },
10103 { "CD", 0x4 },
10104 },
10105};
10106
ebc7a406 10107/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
10108static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10109{
10110 struct alc_spec *spec = codec->spec;
10111 unsigned int mute;
10112
f12ab1e0 10113 if (force || !spec->sense_updated) {
ebc7a406 10114 unsigned int present;
834be88d
TI
10115 /* need to execute and sync at first */
10116 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
10117 /* check laptop HP jack */
10118 present = snd_hda_codec_read(codec, 0x14, 0,
10119 AC_VERB_GET_PIN_SENSE, 0);
10120 /* need to execute and sync at first */
10121 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10122 /* check docking HP jack */
10123 present |= snd_hda_codec_read(codec, 0x1b, 0,
10124 AC_VERB_GET_PIN_SENSE, 0);
10125 if (present & AC_PINSENSE_PRESENCE)
10126 spec->jack_present = 1;
10127 else
10128 spec->jack_present = 0;
834be88d
TI
10129 spec->sense_updated = 1;
10130 }
ebc7a406
TI
10131 /* unmute internal speaker only if both HPs are unplugged and
10132 * master switch is on
10133 */
10134 if (spec->jack_present)
10135 mute = HDA_AMP_MUTE;
10136 else
834be88d 10137 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
10138 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10139 HDA_AMP_MUTE, mute);
834be88d
TI
10140}
10141
10142/* unsolicited event for HP jack sensing */
10143static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10144 unsigned int res)
10145{
10146 if ((res >> 26) != ALC_HP_EVENT)
10147 return;
10148 alc262_fujitsu_automute(codec, 1);
10149}
10150
ebc7a406
TI
10151static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10152{
10153 alc262_fujitsu_automute(codec, 1);
10154}
10155
834be88d 10156/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
10157static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10158 .ops = &snd_hda_bind_vol,
10159 .values = {
10160 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10161 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10162 0
10163 },
10164};
834be88d 10165
0e31daf7
J
10166/* mute/unmute internal speaker according to the hp jack and mute state */
10167static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10168{
10169 struct alc_spec *spec = codec->spec;
10170 unsigned int mute;
10171
10172 if (force || !spec->sense_updated) {
10173 unsigned int present_int_hp;
10174 /* need to execute and sync at first */
10175 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10176 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10177 AC_VERB_GET_PIN_SENSE, 0);
10178 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10179 spec->sense_updated = 1;
10180 }
10181 if (spec->jack_present) {
10182 /* mute internal speaker */
10183 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10184 HDA_AMP_MUTE, HDA_AMP_MUTE);
10185 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10186 HDA_AMP_MUTE, HDA_AMP_MUTE);
10187 } else {
10188 /* unmute internal speaker if necessary */
10189 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10191 HDA_AMP_MUTE, mute);
10192 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10193 HDA_AMP_MUTE, mute);
10194 }
10195}
10196
10197/* unsolicited event for HP jack sensing */
10198static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10199 unsigned int res)
10200{
10201 if ((res >> 26) != ALC_HP_EVENT)
10202 return;
10203 alc262_lenovo_3000_automute(codec, 1);
10204}
10205
834be88d
TI
10206/* bind hp and internal speaker mute (with plug check) */
10207static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10208 struct snd_ctl_elem_value *ucontrol)
10209{
10210 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10211 long *valp = ucontrol->value.integer.value;
10212 int change;
10213
5d9fab2d
TV
10214 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10215 HDA_AMP_MUTE,
10216 valp ? 0 : HDA_AMP_MUTE);
10217 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10218 HDA_AMP_MUTE,
10219 valp ? 0 : HDA_AMP_MUTE);
10220
82beb8fd
TI
10221 if (change)
10222 alc262_fujitsu_automute(codec, 0);
834be88d
TI
10223 return change;
10224}
10225
10226static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 10227 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
10228 {
10229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10230 .name = "Master Playback Switch",
10231 .info = snd_hda_mixer_amp_switch_info,
10232 .get = snd_hda_mixer_amp_switch_get,
10233 .put = alc262_fujitsu_master_sw_put,
10234 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10235 },
10236 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10237 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10238 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
10241 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10242 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10243 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
10244 { } /* end */
10245};
10246
0e31daf7
J
10247/* bind hp and internal speaker mute (with plug check) */
10248static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10249 struct snd_ctl_elem_value *ucontrol)
10250{
10251 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10252 long *valp = ucontrol->value.integer.value;
10253 int change;
10254
10255 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10256 HDA_AMP_MUTE,
10257 valp ? 0 : HDA_AMP_MUTE);
10258
10259 if (change)
10260 alc262_lenovo_3000_automute(codec, 0);
10261 return change;
10262}
10263
10264static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10265 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10266 {
10267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10268 .name = "Master Playback Switch",
10269 .info = snd_hda_mixer_amp_switch_info,
10270 .get = snd_hda_mixer_amp_switch_get,
10271 .put = alc262_lenovo_3000_master_sw_put,
10272 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10273 },
10274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10279 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10280 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10281 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10282 { } /* end */
10283};
10284
9f99a638
HM
10285static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10286 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10287 {
10288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10289 .name = "Master Playback Switch",
10290 .info = snd_hda_mixer_amp_switch_info,
10291 .get = snd_hda_mixer_amp_switch_get,
10292 .put = alc262_sony_master_sw_put,
10293 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10294 },
10295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10297 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10298 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10299 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10300 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10301 { } /* end */
10302};
10303
304dcaac
TI
10304/* additional init verbs for Benq laptops */
10305static struct hda_verb alc262_EAPD_verbs[] = {
10306 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10307 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10308 {}
10309};
10310
83c34218
KY
10311static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10313 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10314
10315 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10316 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10317 {}
10318};
10319
f651b50b
TD
10320/* Samsung Q1 Ultra Vista model setup */
10321static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
10322 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10323 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
10324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10326 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 10327 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
10328 { } /* end */
10329};
10330
10331static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
10332 /* output mixer */
10333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10336 /* speaker */
10337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10338 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10340 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10341 /* HP */
f651b50b 10342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
10343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10347 /* internal mic */
10348 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10350 /* ADC, choose mic */
10351 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
10361 {}
10362};
10363
f651b50b
TD
10364/* mute/unmute internal speaker according to the hp jack and mute state */
10365static void alc262_ultra_automute(struct hda_codec *codec)
10366{
10367 struct alc_spec *spec = codec->spec;
10368 unsigned int mute;
f651b50b 10369
bb9f76cd
TI
10370 mute = 0;
10371 /* auto-mute only when HP is used as HP */
10372 if (!spec->cur_mux[0]) {
10373 unsigned int present;
10374 /* need to execute and sync at first */
10375 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10376 present = snd_hda_codec_read(codec, 0x15, 0,
10377 AC_VERB_GET_PIN_SENSE, 0);
10378 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10379 if (spec->jack_present)
10380 mute = HDA_AMP_MUTE;
f651b50b 10381 }
bb9f76cd
TI
10382 /* mute/unmute internal speaker */
10383 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10384 HDA_AMP_MUTE, mute);
10385 /* mute/unmute HP */
10386 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10387 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
10388}
10389
10390/* unsolicited event for HP jack sensing */
10391static void alc262_ultra_unsol_event(struct hda_codec *codec,
10392 unsigned int res)
10393{
10394 if ((res >> 26) != ALC880_HP_EVENT)
10395 return;
10396 alc262_ultra_automute(codec);
10397}
10398
bb9f76cd
TI
10399static struct hda_input_mux alc262_ultra_capture_source = {
10400 .num_items = 2,
10401 .items = {
10402 { "Mic", 0x1 },
10403 { "Headphone", 0x7 },
10404 },
10405};
10406
10407static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10408 struct snd_ctl_elem_value *ucontrol)
10409{
10410 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10411 struct alc_spec *spec = codec->spec;
10412 int ret;
10413
54cbc9ab 10414 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
10415 if (!ret)
10416 return 0;
10417 /* reprogram the HP pin as mic or HP according to the input source */
10418 snd_hda_codec_write_cache(codec, 0x15, 0,
10419 AC_VERB_SET_PIN_WIDGET_CONTROL,
10420 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10421 alc262_ultra_automute(codec); /* mute/unmute HP */
10422 return ret;
10423}
10424
10425static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10426 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10427 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10428 {
10429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10430 .name = "Capture Source",
54cbc9ab
TI
10431 .info = alc_mux_enum_info,
10432 .get = alc_mux_enum_get,
bb9f76cd
TI
10433 .put = alc262_ultra_mux_enum_put,
10434 },
10435 { } /* end */
10436};
10437
df694daa 10438/* add playback controls from the parsed DAC table */
f12ab1e0
TI
10439static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10440 const struct auto_pin_cfg *cfg)
df694daa
KY
10441{
10442 hda_nid_t nid;
10443 int err;
10444
10445 spec->multiout.num_dacs = 1; /* only use one dac */
10446 spec->multiout.dac_nids = spec->private_dac_nids;
10447 spec->multiout.dac_nids[0] = 2;
10448
10449 nid = cfg->line_out_pins[0];
10450 if (nid) {
f12ab1e0
TI
10451 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10452 "Front Playback Volume",
10453 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10454 if (err < 0)
df694daa 10455 return err;
f12ab1e0
TI
10456 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10457 "Front Playback Switch",
10458 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10459 if (err < 0)
df694daa
KY
10460 return err;
10461 }
10462
82bc955f 10463 nid = cfg->speaker_pins[0];
df694daa
KY
10464 if (nid) {
10465 if (nid == 0x16) {
f12ab1e0
TI
10466 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10467 "Speaker Playback Volume",
10468 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10469 HDA_OUTPUT));
10470 if (err < 0)
df694daa 10471 return err;
f12ab1e0
TI
10472 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10473 "Speaker Playback Switch",
10474 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10475 HDA_OUTPUT));
10476 if (err < 0)
df694daa
KY
10477 return err;
10478 } else {
f12ab1e0
TI
10479 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10480 "Speaker Playback Switch",
10481 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10482 HDA_OUTPUT));
10483 if (err < 0)
df694daa
KY
10484 return err;
10485 }
10486 }
eb06ed8f 10487 nid = cfg->hp_pins[0];
df694daa
KY
10488 if (nid) {
10489 /* spec->multiout.hp_nid = 2; */
10490 if (nid == 0x16) {
f12ab1e0
TI
10491 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10492 "Headphone Playback Volume",
10493 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10494 HDA_OUTPUT));
10495 if (err < 0)
df694daa 10496 return err;
f12ab1e0
TI
10497 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10498 "Headphone Playback Switch",
10499 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10500 HDA_OUTPUT));
10501 if (err < 0)
df694daa
KY
10502 return err;
10503 } else {
f12ab1e0
TI
10504 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10505 "Headphone Playback Switch",
10506 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10507 HDA_OUTPUT));
10508 if (err < 0)
df694daa
KY
10509 return err;
10510 }
10511 }
f12ab1e0 10512 return 0;
df694daa
KY
10513}
10514
10515/* identical with ALC880 */
f12ab1e0
TI
10516#define alc262_auto_create_analog_input_ctls \
10517 alc880_auto_create_analog_input_ctls
df694daa
KY
10518
10519/*
10520 * generic initialization of ADC, input mixers and output mixers
10521 */
10522static struct hda_verb alc262_volume_init_verbs[] = {
10523 /*
10524 * Unmute ADC0-2 and set the default input to mic-in
10525 */
10526 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10528 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10530 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10532
cb53c626 10533 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10534 * mixer widget
f12ab1e0
TI
10535 * Note: PASD motherboards uses the Line In 2 as the input for
10536 * front panel mic (mic 2)
df694daa
KY
10537 */
10538 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10544
10545 /*
10546 * Set up output mixers (0x0c - 0x0f)
10547 */
10548 /* set vol=0 to output mixers */
10549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10552
df694daa
KY
10553 /* set up input amps for analog loopback */
10554 /* Amp Indices: DAC = 0, mixer = 1 */
10555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10559 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10561
10562 /* FIXME: use matrix-type input source selection */
10563 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10564 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10569 /* Input mixer2 */
10570 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10574 /* Input mixer3 */
10575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10579
10580 { }
10581};
10582
9c7f852e
TI
10583static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10584 /*
10585 * Unmute ADC0-2 and set the default input to mic-in
10586 */
10587 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10589 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10593
cb53c626 10594 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10595 * mixer widget
f12ab1e0
TI
10596 * Note: PASD motherboards uses the Line In 2 as the input for
10597 * front panel mic (mic 2)
9c7f852e
TI
10598 */
10599 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10607
9c7f852e
TI
10608 /*
10609 * Set up output mixers (0x0c - 0x0e)
10610 */
10611 /* set vol=0 to output mixers */
10612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10614 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10615
10616 /* set up input amps for analog loopback */
10617 /* Amp Indices: DAC = 0, mixer = 1 */
10618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10624
ce875f07 10625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10627 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10628
10629 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10630 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10631
10632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10634
10635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10638 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10639 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10640
10641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10644 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10645 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10646 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10647
10648
10649 /* FIXME: use matrix-type input source selection */
10650 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10651 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10656 /* Input mixer2 */
10657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10661 /* Input mixer3 */
10662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10666
ce875f07
TI
10667 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10668
9c7f852e
TI
10669 { }
10670};
10671
cd7509a4
KY
10672static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10673 /*
10674 * Unmute ADC0-2 and set the default input to mic-in
10675 */
10676 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10678 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10680 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10681 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10682
cb53c626 10683 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10684 * mixer widget
10685 * Note: PASD motherboards uses the Line In 2 as the input for front
10686 * panel mic (mic 2)
10687 */
10688 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10697 /*
10698 * Set up output mixers (0x0c - 0x0e)
10699 */
10700 /* set vol=0 to output mixers */
10701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10704
10705 /* set up input amps for analog loopback */
10706 /* Amp Indices: DAC = 0, mixer = 1 */
10707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10713
10714
10715 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10722
10723 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10725
10726 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10728
10729 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10730 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10731 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10733 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10734 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10735
10736 /* FIXME: use matrix-type input source selection */
10737 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10738 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10744 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10746 /* Input mixer2 */
10747 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10749 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10752 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10754 /* Input mixer3 */
10755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10760 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10762
ce875f07
TI
10763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10764
cd7509a4
KY
10765 { }
10766};
10767
9f99a638
HM
10768static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10769
10770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10772 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10773
10774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10775 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10777 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10778
10779 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10781 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10782 {}
10783};
10784
10785
cb53c626
TI
10786#ifdef CONFIG_SND_HDA_POWER_SAVE
10787#define alc262_loopbacks alc880_loopbacks
10788#endif
10789
df694daa
KY
10790/* pcm configuration: identiacal with ALC880 */
10791#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10792#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10793#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10794#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10795
10796/*
10797 * BIOS auto configuration
10798 */
10799static int alc262_parse_auto_config(struct hda_codec *codec)
10800{
10801 struct alc_spec *spec = codec->spec;
10802 int err;
10803 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10804
f12ab1e0
TI
10805 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10806 alc262_ignore);
10807 if (err < 0)
df694daa 10808 return err;
e64f14f4 10809 if (!spec->autocfg.line_outs) {
0852d7a6 10810 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
10811 spec->multiout.max_channels = 2;
10812 spec->no_analog = 1;
10813 goto dig_only;
10814 }
df694daa 10815 return 0; /* can't find valid BIOS pin config */
e64f14f4 10816 }
f12ab1e0
TI
10817 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10818 if (err < 0)
10819 return err;
10820 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10821 if (err < 0)
df694daa
KY
10822 return err;
10823
10824 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10825
e64f14f4 10826 dig_only:
0852d7a6 10827 if (spec->autocfg.dig_outs) {
df694daa 10828 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 10829 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 10830 }
df694daa
KY
10831 if (spec->autocfg.dig_in_pin)
10832 spec->dig_in_nid = ALC262_DIGIN_NID;
10833
603c4019 10834 if (spec->kctls.list)
d88897ea 10835 add_mixer(spec, spec->kctls.list);
df694daa 10836
d88897ea 10837 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 10838 spec->num_mux_defs = 1;
61b9b9b1 10839 spec->input_mux = &spec->private_imux[0];
df694daa 10840
776e184e
TI
10841 err = alc_auto_add_mic_boost(codec);
10842 if (err < 0)
10843 return err;
10844
df694daa
KY
10845 return 1;
10846}
10847
10848#define alc262_auto_init_multi_out alc882_auto_init_multi_out
10849#define alc262_auto_init_hp_out alc882_auto_init_hp_out
10850#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 10851#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
10852
10853
10854/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 10855static void alc262_auto_init(struct hda_codec *codec)
df694daa 10856{
f6c7e546 10857 struct alc_spec *spec = codec->spec;
df694daa
KY
10858 alc262_auto_init_multi_out(codec);
10859 alc262_auto_init_hp_out(codec);
10860 alc262_auto_init_analog_input(codec);
f511b01c 10861 alc262_auto_init_input_src(codec);
f6c7e546 10862 if (spec->unsol_event)
7fb0d78f 10863 alc_inithook(codec);
df694daa
KY
10864}
10865
10866/*
10867 * configuration and preset
10868 */
f5fcc13c
TI
10869static const char *alc262_models[ALC262_MODEL_LAST] = {
10870 [ALC262_BASIC] = "basic",
10871 [ALC262_HIPPO] = "hippo",
10872 [ALC262_HIPPO_1] = "hippo_1",
10873 [ALC262_FUJITSU] = "fujitsu",
10874 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 10875 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 10876 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 10877 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 10878 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
10879 [ALC262_BENQ_T31] = "benq-t31",
10880 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 10881 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 10882 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 10883 [ALC262_ULTRA] = "ultra",
0e31daf7 10884 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 10885 [ALC262_NEC] = "nec",
ba340e82 10886 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
10887 [ALC262_AUTO] = "auto",
10888};
10889
10890static struct snd_pci_quirk alc262_cfg_tbl[] = {
10891 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 10892 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
10893 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10894 ALC262_HP_BPC),
10895 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10896 ALC262_HP_BPC),
53eff7e1
TI
10897 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10898 ALC262_HP_BPC),
cd7509a4 10899 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10900 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10901 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10902 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10903 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10904 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10905 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10906 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
10907 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10908 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10909 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
10910 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10911 ALC262_HP_TC_T5735),
8c427226 10912 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 10913 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 10914 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 10915 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 10916 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
f872a919
TI
10917 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10918 ALC262_SONY_ASSAMD),
36ca6e13 10919 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 10920 ALC262_TOSHIBA_RX1),
80ffe869 10921 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 10922 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 10923 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 10924 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
10925 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10926 ALC262_ULTRA),
3e420e78 10927 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 10928 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
10929 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10930 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10931 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
10932 {}
10933};
10934
10935static struct alc_config_preset alc262_presets[] = {
10936 [ALC262_BASIC] = {
10937 .mixers = { alc262_base_mixer },
10938 .init_verbs = { alc262_init_verbs },
10939 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10940 .dac_nids = alc262_dac_nids,
10941 .hp_nid = 0x03,
10942 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10943 .channel_mode = alc262_modes,
a3bcba38 10944 .input_mux = &alc262_capture_source,
df694daa 10945 },
ccc656ce
KY
10946 [ALC262_HIPPO] = {
10947 .mixers = { alc262_base_mixer },
10948 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10949 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10950 .dac_nids = alc262_dac_nids,
10951 .hp_nid = 0x03,
10952 .dig_out_nid = ALC262_DIGOUT_NID,
10953 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10954 .channel_mode = alc262_modes,
10955 .input_mux = &alc262_capture_source,
10956 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10957 .init_hook = alc262_hippo_automute,
ccc656ce
KY
10958 },
10959 [ALC262_HIPPO_1] = {
10960 .mixers = { alc262_hippo1_mixer },
10961 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10962 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10963 .dac_nids = alc262_dac_nids,
10964 .hp_nid = 0x02,
10965 .dig_out_nid = ALC262_DIGOUT_NID,
10966 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10967 .channel_mode = alc262_modes,
10968 .input_mux = &alc262_capture_source,
10969 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 10970 .init_hook = alc262_hippo1_automute,
ccc656ce 10971 },
834be88d
TI
10972 [ALC262_FUJITSU] = {
10973 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
10974 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10975 alc262_fujitsu_unsol_verbs },
834be88d
TI
10976 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10977 .dac_nids = alc262_dac_nids,
10978 .hp_nid = 0x03,
10979 .dig_out_nid = ALC262_DIGOUT_NID,
10980 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10981 .channel_mode = alc262_modes,
10982 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 10983 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 10984 .init_hook = alc262_fujitsu_init_hook,
834be88d 10985 },
9c7f852e
TI
10986 [ALC262_HP_BPC] = {
10987 .mixers = { alc262_HP_BPC_mixer },
10988 .init_verbs = { alc262_HP_BPC_init_verbs },
10989 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10990 .dac_nids = alc262_dac_nids,
10991 .hp_nid = 0x03,
10992 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10993 .channel_mode = alc262_modes,
10994 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
10995 .unsol_event = alc262_hp_bpc_unsol_event,
10996 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 10997 },
cd7509a4
KY
10998 [ALC262_HP_BPC_D7000_WF] = {
10999 .mixers = { alc262_HP_BPC_WildWest_mixer },
11000 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11001 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11002 .dac_nids = alc262_dac_nids,
11003 .hp_nid = 0x03,
11004 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11005 .channel_mode = alc262_modes,
accbe498 11006 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11007 .unsol_event = alc262_hp_wildwest_unsol_event,
11008 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11009 },
cd7509a4
KY
11010 [ALC262_HP_BPC_D7000_WL] = {
11011 .mixers = { alc262_HP_BPC_WildWest_mixer,
11012 alc262_HP_BPC_WildWest_option_mixer },
11013 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11014 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11015 .dac_nids = alc262_dac_nids,
11016 .hp_nid = 0x03,
11017 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11018 .channel_mode = alc262_modes,
accbe498 11019 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11020 .unsol_event = alc262_hp_wildwest_unsol_event,
11021 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11022 },
66d2a9d6
KY
11023 [ALC262_HP_TC_T5735] = {
11024 .mixers = { alc262_hp_t5735_mixer },
11025 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11026 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11027 .dac_nids = alc262_dac_nids,
11028 .hp_nid = 0x03,
11029 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11030 .channel_mode = alc262_modes,
11031 .input_mux = &alc262_capture_source,
11032 .unsol_event = alc262_hp_t5735_unsol_event,
11033 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
11034 },
11035 [ALC262_HP_RP5700] = {
11036 .mixers = { alc262_hp_rp5700_mixer },
11037 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11038 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11039 .dac_nids = alc262_dac_nids,
11040 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11041 .channel_mode = alc262_modes,
11042 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 11043 },
304dcaac
TI
11044 [ALC262_BENQ_ED8] = {
11045 .mixers = { alc262_base_mixer },
11046 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11047 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11048 .dac_nids = alc262_dac_nids,
11049 .hp_nid = 0x03,
11050 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11051 .channel_mode = alc262_modes,
11052 .input_mux = &alc262_capture_source,
f12ab1e0 11053 },
272a527c
KY
11054 [ALC262_SONY_ASSAMD] = {
11055 .mixers = { alc262_sony_mixer },
11056 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11057 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11058 .dac_nids = alc262_dac_nids,
11059 .hp_nid = 0x02,
11060 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11061 .channel_mode = alc262_modes,
11062 .input_mux = &alc262_capture_source,
11063 .unsol_event = alc262_hippo_unsol_event,
5b31954e 11064 .init_hook = alc262_hippo_automute,
83c34218
KY
11065 },
11066 [ALC262_BENQ_T31] = {
11067 .mixers = { alc262_benq_t31_mixer },
11068 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11069 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11070 .dac_nids = alc262_dac_nids,
11071 .hp_nid = 0x03,
11072 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11073 .channel_mode = alc262_modes,
11074 .input_mux = &alc262_capture_source,
11075 .unsol_event = alc262_hippo_unsol_event,
5b31954e 11076 .init_hook = alc262_hippo_automute,
ea1fb29a 11077 },
f651b50b 11078 [ALC262_ULTRA] = {
f9e336f6
TI
11079 .mixers = { alc262_ultra_mixer },
11080 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 11081 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
11082 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11083 .dac_nids = alc262_dac_nids,
f651b50b
TD
11084 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11085 .channel_mode = alc262_modes,
11086 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
11087 .adc_nids = alc262_adc_nids, /* ADC0 */
11088 .capsrc_nids = alc262_capsrc_nids,
11089 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
11090 .unsol_event = alc262_ultra_unsol_event,
11091 .init_hook = alc262_ultra_automute,
11092 },
0e31daf7
J
11093 [ALC262_LENOVO_3000] = {
11094 .mixers = { alc262_lenovo_3000_mixer },
11095 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11096 alc262_lenovo_3000_unsol_verbs },
11097 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11098 .dac_nids = alc262_dac_nids,
11099 .hp_nid = 0x03,
11100 .dig_out_nid = ALC262_DIGOUT_NID,
11101 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11102 .channel_mode = alc262_modes,
11103 .input_mux = &alc262_fujitsu_capture_source,
11104 .unsol_event = alc262_lenovo_3000_unsol_event,
11105 },
e8f9ae2a
PT
11106 [ALC262_NEC] = {
11107 .mixers = { alc262_nec_mixer },
11108 .init_verbs = { alc262_nec_verbs },
11109 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11110 .dac_nids = alc262_dac_nids,
11111 .hp_nid = 0x03,
11112 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11113 .channel_mode = alc262_modes,
11114 .input_mux = &alc262_capture_source,
11115 },
4e555fe5
KY
11116 [ALC262_TOSHIBA_S06] = {
11117 .mixers = { alc262_toshiba_s06_mixer },
11118 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11119 alc262_eapd_verbs },
11120 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11121 .capsrc_nids = alc262_dmic_capsrc_nids,
11122 .dac_nids = alc262_dac_nids,
11123 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11124 .dig_out_nid = ALC262_DIGOUT_NID,
11125 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11126 .channel_mode = alc262_modes,
11127 .input_mux = &alc262_dmic_capture_source,
11128 .unsol_event = alc262_toshiba_s06_unsol_event,
11129 .init_hook = alc262_toshiba_s06_init_hook,
11130 },
9f99a638
HM
11131 [ALC262_TOSHIBA_RX1] = {
11132 .mixers = { alc262_toshiba_rx1_mixer },
11133 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11134 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11135 .dac_nids = alc262_dac_nids,
11136 .hp_nid = 0x03,
11137 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11138 .channel_mode = alc262_modes,
11139 .input_mux = &alc262_capture_source,
11140 .unsol_event = alc262_hippo_unsol_event,
11141 .init_hook = alc262_hippo_automute,
11142 },
ba340e82
TV
11143 [ALC262_TYAN] = {
11144 .mixers = { alc262_tyan_mixer },
11145 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11146 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11147 .dac_nids = alc262_dac_nids,
11148 .hp_nid = 0x02,
11149 .dig_out_nid = ALC262_DIGOUT_NID,
11150 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11151 .channel_mode = alc262_modes,
11152 .input_mux = &alc262_capture_source,
11153 .unsol_event = alc262_tyan_unsol_event,
11154 .init_hook = alc262_tyan_automute,
11155 },
df694daa
KY
11156};
11157
11158static int patch_alc262(struct hda_codec *codec)
11159{
11160 struct alc_spec *spec;
11161 int board_config;
11162 int err;
11163
dc041e0b 11164 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11165 if (spec == NULL)
11166 return -ENOMEM;
11167
11168 codec->spec = spec;
11169#if 0
f12ab1e0
TI
11170 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11171 * under-run
11172 */
df694daa
KY
11173 {
11174 int tmp;
11175 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11176 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11177 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11178 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11179 }
11180#endif
11181
2c3bf9ab
TI
11182 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11183
f5fcc13c
TI
11184 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11185 alc262_models,
11186 alc262_cfg_tbl);
cd7509a4 11187
f5fcc13c 11188 if (board_config < 0) {
9c7f852e
TI
11189 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11190 "trying auto-probe from BIOS...\n");
df694daa
KY
11191 board_config = ALC262_AUTO;
11192 }
11193
11194 if (board_config == ALC262_AUTO) {
11195 /* automatic parse from the BIOS config */
11196 err = alc262_parse_auto_config(codec);
11197 if (err < 0) {
11198 alc_free(codec);
11199 return err;
f12ab1e0 11200 } else if (!err) {
9c7f852e
TI
11201 printk(KERN_INFO
11202 "hda_codec: Cannot set up configuration "
11203 "from BIOS. Using base mode...\n");
df694daa
KY
11204 board_config = ALC262_BASIC;
11205 }
11206 }
11207
07eba61d
TI
11208 if (!spec->no_analog) {
11209 err = snd_hda_attach_beep_device(codec, 0x1);
11210 if (err < 0) {
11211 alc_free(codec);
11212 return err;
11213 }
680cd536
KK
11214 }
11215
df694daa
KY
11216 if (board_config != ALC262_AUTO)
11217 setup_preset(spec, &alc262_presets[board_config]);
11218
11219 spec->stream_name_analog = "ALC262 Analog";
11220 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11221 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 11222
df694daa
KY
11223 spec->stream_name_digital = "ALC262 Digital";
11224 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11225 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11226
61b9b9b1 11227 spec->capture_style = CAPT_MIX;
f12ab1e0 11228 if (!spec->adc_nids && spec->input_mux) {
df694daa 11229 /* check whether NID 0x07 is valid */
4a471b7d
TI
11230 unsigned int wcap = get_wcaps(codec, 0x07);
11231
f12ab1e0
TI
11232 /* get type */
11233 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
11234 if (wcap != AC_WID_AUD_IN) {
11235 spec->adc_nids = alc262_adc_nids_alt;
11236 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 11237 spec->capsrc_nids = alc262_capsrc_nids_alt;
df694daa
KY
11238 } else {
11239 spec->adc_nids = alc262_adc_nids;
11240 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 11241 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
11242 }
11243 }
e64f14f4 11244 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 11245 set_capture_mixer(spec);
07eba61d
TI
11246 if (!spec->no_analog)
11247 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 11248
2134ea4f
TI
11249 spec->vmaster_nid = 0x0c;
11250
df694daa
KY
11251 codec->patch_ops = alc_patch_ops;
11252 if (board_config == ALC262_AUTO)
ae6b813a 11253 spec->init_hook = alc262_auto_init;
cb53c626
TI
11254#ifdef CONFIG_SND_HDA_POWER_SAVE
11255 if (!spec->loopback.amplist)
11256 spec->loopback.amplist = alc262_loopbacks;
11257#endif
daead538 11258 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 11259
df694daa
KY
11260 return 0;
11261}
11262
a361d84b
KY
11263/*
11264 * ALC268 channel source setting (2 channel)
11265 */
11266#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11267#define alc268_modes alc260_modes
ea1fb29a 11268
a361d84b
KY
11269static hda_nid_t alc268_dac_nids[2] = {
11270 /* front, hp */
11271 0x02, 0x03
11272};
11273
11274static hda_nid_t alc268_adc_nids[2] = {
11275 /* ADC0-1 */
11276 0x08, 0x07
11277};
11278
11279static hda_nid_t alc268_adc_nids_alt[1] = {
11280 /* ADC0 */
11281 0x08
11282};
11283
e1406348
TI
11284static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11285
a361d84b
KY
11286static struct snd_kcontrol_new alc268_base_mixer[] = {
11287 /* output mixer control */
11288 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11289 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
11292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
11295 { }
11296};
11297
aef9d318
TI
11298/* bind Beep switches of both NID 0x0f and 0x10 */
11299static struct hda_bind_ctls alc268_bind_beep_sw = {
11300 .ops = &snd_hda_bind_sw,
11301 .values = {
11302 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11303 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11304 0
11305 },
11306};
11307
11308static struct snd_kcontrol_new alc268_beep_mixer[] = {
11309 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11310 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11311 { }
11312};
11313
d1a991a6
KY
11314static struct hda_verb alc268_eapd_verbs[] = {
11315 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11316 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11317 { }
11318};
11319
d273809e
TI
11320/* Toshiba specific */
11321#define alc268_toshiba_automute alc262_hippo_automute
11322
11323static struct hda_verb alc268_toshiba_verbs[] = {
11324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11325 { } /* end */
11326};
11327
8ef355da
KY
11328static struct hda_input_mux alc268_acer_lc_capture_source = {
11329 .num_items = 2,
11330 .items = {
11331 { "i-Mic", 0x6 },
11332 { "E-Mic", 0x0 },
11333 },
11334};
11335
d273809e 11336/* Acer specific */
889c4395 11337/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
11338static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11339 .ops = &snd_hda_bind_vol,
11340 .values = {
11341 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11342 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11343 0
11344 },
11345};
11346
889c4395
TI
11347/* mute/unmute internal speaker according to the hp jack and mute state */
11348static void alc268_acer_automute(struct hda_codec *codec, int force)
11349{
11350 struct alc_spec *spec = codec->spec;
11351 unsigned int mute;
11352
11353 if (force || !spec->sense_updated) {
11354 unsigned int present;
11355 present = snd_hda_codec_read(codec, 0x14, 0,
11356 AC_VERB_GET_PIN_SENSE, 0);
11357 spec->jack_present = (present & 0x80000000) != 0;
11358 spec->sense_updated = 1;
11359 }
11360 if (spec->jack_present)
11361 mute = HDA_AMP_MUTE; /* mute internal speaker */
11362 else /* unmute internal speaker if necessary */
11363 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11364 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11365 HDA_AMP_MUTE, mute);
11366}
11367
11368
11369/* bind hp and internal speaker mute (with plug check) */
11370static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11371 struct snd_ctl_elem_value *ucontrol)
11372{
11373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11374 long *valp = ucontrol->value.integer.value;
11375 int change;
11376
11377 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11378 HDA_AMP_MUTE,
11379 valp[0] ? 0 : HDA_AMP_MUTE);
11380 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11381 HDA_AMP_MUTE,
11382 valp[1] ? 0 : HDA_AMP_MUTE);
11383 if (change)
11384 alc268_acer_automute(codec, 0);
11385 return change;
11386}
d273809e 11387
8ef355da
KY
11388static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11389 /* output mixer control */
11390 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11391 {
11392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11393 .name = "Master Playback Switch",
11394 .info = snd_hda_mixer_amp_switch_info,
11395 .get = snd_hda_mixer_amp_switch_get,
11396 .put = alc268_acer_master_sw_put,
11397 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11398 },
11399 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11400 { }
11401};
11402
d273809e
TI
11403static struct snd_kcontrol_new alc268_acer_mixer[] = {
11404 /* output mixer control */
11405 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11406 {
11407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11408 .name = "Master Playback Switch",
11409 .info = snd_hda_mixer_amp_switch_info,
11410 .get = snd_hda_mixer_amp_switch_get,
11411 .put = alc268_acer_master_sw_put,
11412 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11413 },
33bf17ab
TI
11414 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11415 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11416 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
11417 { }
11418};
11419
c238b4f4
TI
11420static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11421 /* output mixer control */
11422 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11423 {
11424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11425 .name = "Master Playback Switch",
11426 .info = snd_hda_mixer_amp_switch_info,
11427 .get = snd_hda_mixer_amp_switch_get,
11428 .put = alc268_acer_master_sw_put,
11429 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11430 },
11431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11432 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11433 { }
11434};
11435
8ef355da
KY
11436static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11437 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11440 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11441 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11442 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11443 { }
11444};
11445
d273809e 11446static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
11447 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11448 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
11449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
11451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
11453 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11454 { }
11455};
11456
11457/* unsolicited event for HP jack sensing */
11458static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11459 unsigned int res)
11460{
889c4395 11461 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11462 return;
11463 alc268_toshiba_automute(codec);
11464}
11465
11466static void alc268_acer_unsol_event(struct hda_codec *codec,
11467 unsigned int res)
11468{
889c4395 11469 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11470 return;
11471 alc268_acer_automute(codec, 1);
11472}
11473
889c4395
TI
11474static void alc268_acer_init_hook(struct hda_codec *codec)
11475{
11476 alc268_acer_automute(codec, 1);
11477}
11478
8ef355da
KY
11479/* toggle speaker-output according to the hp-jack state */
11480static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11481{
11482 unsigned int present;
11483 unsigned char bits;
11484
11485 present = snd_hda_codec_read(codec, 0x15, 0,
11486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11487 bits = present ? AMP_IN_MUTE(0) : 0;
11488 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11489 AMP_IN_MUTE(0), bits);
11490 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11491 AMP_IN_MUTE(0), bits);
11492}
11493
11494
11495static void alc268_acer_mic_automute(struct hda_codec *codec)
11496{
11497 unsigned int present;
11498
11499 present = snd_hda_codec_read(codec, 0x18, 0,
11500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11501 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11502 present ? 0x0 : 0x6);
11503}
11504
11505static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11506 unsigned int res)
11507{
11508 if ((res >> 26) == ALC880_HP_EVENT)
11509 alc268_aspire_one_speaker_automute(codec);
11510 if ((res >> 26) == ALC880_MIC_EVENT)
11511 alc268_acer_mic_automute(codec);
11512}
11513
11514static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11515{
11516 alc268_aspire_one_speaker_automute(codec);
11517 alc268_acer_mic_automute(codec);
11518}
11519
3866f0b0
TI
11520static struct snd_kcontrol_new alc268_dell_mixer[] = {
11521 /* output mixer control */
11522 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11523 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11524 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11525 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11526 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11527 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11528 { }
11529};
11530
11531static struct hda_verb alc268_dell_verbs[] = {
11532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11534 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11535 { }
11536};
11537
11538/* mute/unmute internal speaker according to the hp jack and mute state */
11539static void alc268_dell_automute(struct hda_codec *codec)
11540{
11541 unsigned int present;
11542 unsigned int mute;
11543
11544 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11545 if (present & 0x80000000)
11546 mute = HDA_AMP_MUTE;
11547 else
11548 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11549 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11550 HDA_AMP_MUTE, mute);
11551}
11552
11553static void alc268_dell_unsol_event(struct hda_codec *codec,
11554 unsigned int res)
11555{
11556 if ((res >> 26) != ALC880_HP_EVENT)
11557 return;
11558 alc268_dell_automute(codec);
11559}
11560
11561#define alc268_dell_init_hook alc268_dell_automute
11562
eb5a6621
HRK
11563static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11564 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11565 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11567 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11568 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11569 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11570 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11571 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11572 { }
11573};
11574
11575static struct hda_verb alc267_quanta_il1_verbs[] = {
11576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11578 { }
11579};
11580
11581static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11582{
11583 unsigned int present;
11584
11585 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11586 & AC_PINSENSE_PRESENCE;
11587 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11588 present ? 0 : PIN_OUT);
11589}
11590
11591static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11592{
11593 unsigned int present;
11594
11595 present = snd_hda_codec_read(codec, 0x18, 0,
11596 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11597 snd_hda_codec_write(codec, 0x23, 0,
11598 AC_VERB_SET_CONNECT_SEL,
11599 present ? 0x00 : 0x01);
11600}
11601
11602static void alc267_quanta_il1_automute(struct hda_codec *codec)
11603{
11604 alc267_quanta_il1_hp_automute(codec);
11605 alc267_quanta_il1_mic_automute(codec);
11606}
11607
11608static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11609 unsigned int res)
11610{
11611 switch (res >> 26) {
11612 case ALC880_HP_EVENT:
11613 alc267_quanta_il1_hp_automute(codec);
11614 break;
11615 case ALC880_MIC_EVENT:
11616 alc267_quanta_il1_mic_automute(codec);
11617 break;
11618 }
11619}
11620
a361d84b
KY
11621/*
11622 * generic initialization of ADC, input mixers and output mixers
11623 */
11624static struct hda_verb alc268_base_init_verbs[] = {
11625 /* Unmute DAC0-1 and set vol = 0 */
11626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 11627 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11628
11629 /*
11630 * Set up output mixers (0x0c - 0x0e)
11631 */
11632 /* set vol=0 to output mixers */
11633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11634 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11635
11636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11637 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11638
11639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11641 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11642 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11643 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11644 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11645 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11646 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11647
11648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11650 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
11653
11654 /* set PCBEEP vol = 0, mute connections */
11655 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11657 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 11658
a9b3aa8a 11659 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 11660
a9b3aa8a
JZ
11661 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11663 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11665
a361d84b
KY
11666 { }
11667};
11668
11669/*
11670 * generic initialization of ADC, input mixers and output mixers
11671 */
11672static struct hda_verb alc268_volume_init_verbs[] = {
11673 /* set output DAC */
4cfb91c6
TI
11674 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11675 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11676
11677 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11678 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11680 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11681 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11682
a361d84b 11683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11686
11687 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11689
aef9d318
TI
11690 /* set PCBEEP vol = 0, mute connections */
11691 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11692 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11693 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11694
11695 { }
11696};
11697
a361d84b
KY
11698static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11699 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11700 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11701 {
11702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11703 /* The multiple "Capture Source" controls confuse alsamixer
11704 * So call somewhat different..
a361d84b
KY
11705 */
11706 /* .name = "Capture Source", */
11707 .name = "Input Source",
11708 .count = 1,
54cbc9ab
TI
11709 .info = alc_mux_enum_info,
11710 .get = alc_mux_enum_get,
11711 .put = alc_mux_enum_put,
a361d84b
KY
11712 },
11713 { } /* end */
11714};
11715
11716static struct snd_kcontrol_new alc268_capture_mixer[] = {
11717 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11718 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11719 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11720 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11721 {
11722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11723 /* The multiple "Capture Source" controls confuse alsamixer
11724 * So call somewhat different..
a361d84b
KY
11725 */
11726 /* .name = "Capture Source", */
11727 .name = "Input Source",
11728 .count = 2,
54cbc9ab
TI
11729 .info = alc_mux_enum_info,
11730 .get = alc_mux_enum_get,
11731 .put = alc_mux_enum_put,
a361d84b
KY
11732 },
11733 { } /* end */
11734};
11735
11736static struct hda_input_mux alc268_capture_source = {
11737 .num_items = 4,
11738 .items = {
11739 { "Mic", 0x0 },
11740 { "Front Mic", 0x1 },
11741 { "Line", 0x2 },
11742 { "CD", 0x3 },
11743 },
11744};
11745
0ccb541c 11746static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
11747 .num_items = 3,
11748 .items = {
11749 { "Mic", 0x0 },
11750 { "Internal Mic", 0x1 },
11751 { "Line", 0x2 },
11752 },
11753};
11754
11755static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
11756 .num_items = 3,
11757 .items = {
11758 { "Mic", 0x0 },
11759 { "Internal Mic", 0x6 },
11760 { "Line", 0x2 },
11761 },
11762};
11763
86c53bd2
JW
11764#ifdef CONFIG_SND_DEBUG
11765static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11766 /* Volume widgets */
11767 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11768 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11769 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11770 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11771 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11772 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11773 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11774 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11775 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11776 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11777 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11778 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11779 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11780 /* The below appears problematic on some hardwares */
11781 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11782 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11783 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11784 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11785 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11786
11787 /* Modes for retasking pin widgets */
11788 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11789 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11790 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11791 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11792
11793 /* Controls for GPIO pins, assuming they are configured as outputs */
11794 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11795 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11796 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11797 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11798
11799 /* Switches to allow the digital SPDIF output pin to be enabled.
11800 * The ALC268 does not have an SPDIF input.
11801 */
11802 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11803
11804 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11805 * this output to turn on an external amplifier.
11806 */
11807 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11808 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11809
11810 { } /* end */
11811};
11812#endif
11813
a361d84b
KY
11814/* create input playback/capture controls for the given pin */
11815static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11816 const char *ctlname, int idx)
11817{
11818 char name[32];
11819 int err;
11820
11821 sprintf(name, "%s Playback Volume", ctlname);
11822 if (nid == 0x14) {
11823 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11824 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11825 HDA_OUTPUT));
11826 if (err < 0)
11827 return err;
11828 } else if (nid == 0x15) {
11829 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11830 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11831 HDA_OUTPUT));
11832 if (err < 0)
11833 return err;
11834 } else
11835 return -1;
11836 sprintf(name, "%s Playback Switch", ctlname);
11837 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11838 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11839 if (err < 0)
11840 return err;
11841 return 0;
11842}
11843
11844/* add playback controls from the parsed DAC table */
11845static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11846 const struct auto_pin_cfg *cfg)
11847{
11848 hda_nid_t nid;
11849 int err;
11850
11851 spec->multiout.num_dacs = 2; /* only use one dac */
11852 spec->multiout.dac_nids = spec->private_dac_nids;
11853 spec->multiout.dac_nids[0] = 2;
11854 spec->multiout.dac_nids[1] = 3;
11855
11856 nid = cfg->line_out_pins[0];
11857 if (nid)
ea1fb29a 11858 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
11859
11860 nid = cfg->speaker_pins[0];
11861 if (nid == 0x1d) {
11862 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11863 "Speaker Playback Volume",
11864 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11865 if (err < 0)
11866 return err;
11867 }
11868 nid = cfg->hp_pins[0];
11869 if (nid)
11870 alc268_new_analog_output(spec, nid, "Headphone", 0);
11871
11872 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11873 if (nid == 0x16) {
11874 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11875 "Mono Playback Switch",
11876 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11877 if (err < 0)
11878 return err;
11879 }
ea1fb29a 11880 return 0;
a361d84b
KY
11881}
11882
11883/* create playback/capture controls for input pins */
11884static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11885 const struct auto_pin_cfg *cfg)
11886{
61b9b9b1 11887 struct hda_input_mux *imux = &spec->private_imux[0];
a361d84b
KY
11888 int i, idx1;
11889
11890 for (i = 0; i < AUTO_PIN_LAST; i++) {
11891 switch(cfg->input_pins[i]) {
11892 case 0x18:
11893 idx1 = 0; /* Mic 1 */
11894 break;
11895 case 0x19:
11896 idx1 = 1; /* Mic 2 */
11897 break;
11898 case 0x1a:
11899 idx1 = 2; /* Line In */
11900 break;
ea1fb29a 11901 case 0x1c:
a361d84b
KY
11902 idx1 = 3; /* CD */
11903 break;
7194cae6
TI
11904 case 0x12:
11905 case 0x13:
11906 idx1 = 6; /* digital mics */
11907 break;
a361d84b
KY
11908 default:
11909 continue;
11910 }
11911 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11912 imux->items[imux->num_items].index = idx1;
ea1fb29a 11913 imux->num_items++;
a361d84b
KY
11914 }
11915 return 0;
11916}
11917
11918static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11919{
11920 struct alc_spec *spec = codec->spec;
11921 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11922 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11923 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11924 unsigned int dac_vol1, dac_vol2;
11925
11926 if (speaker_nid) {
11927 snd_hda_codec_write(codec, speaker_nid, 0,
11928 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11929 snd_hda_codec_write(codec, 0x0f, 0,
11930 AC_VERB_SET_AMP_GAIN_MUTE,
11931 AMP_IN_UNMUTE(1));
11932 snd_hda_codec_write(codec, 0x10, 0,
11933 AC_VERB_SET_AMP_GAIN_MUTE,
11934 AMP_IN_UNMUTE(1));
11935 } else {
11936 snd_hda_codec_write(codec, 0x0f, 0,
11937 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11938 snd_hda_codec_write(codec, 0x10, 0,
11939 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11940 }
11941
11942 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 11943 if (line_nid == 0x14)
a361d84b
KY
11944 dac_vol2 = AMP_OUT_ZERO;
11945 else if (line_nid == 0x15)
11946 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 11947 if (hp_nid == 0x14)
a361d84b
KY
11948 dac_vol2 = AMP_OUT_ZERO;
11949 else if (hp_nid == 0x15)
11950 dac_vol1 = AMP_OUT_ZERO;
11951 if (line_nid != 0x16 || hp_nid != 0x16 ||
11952 spec->autocfg.line_out_pins[1] != 0x16 ||
11953 spec->autocfg.line_out_pins[2] != 0x16)
11954 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11955
11956 snd_hda_codec_write(codec, 0x02, 0,
11957 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11958 snd_hda_codec_write(codec, 0x03, 0,
11959 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11960}
11961
11962/* pcm configuration: identiacal with ALC880 */
11963#define alc268_pcm_analog_playback alc880_pcm_analog_playback
11964#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 11965#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
11966#define alc268_pcm_digital_playback alc880_pcm_digital_playback
11967
11968/*
11969 * BIOS auto configuration
11970 */
11971static int alc268_parse_auto_config(struct hda_codec *codec)
11972{
11973 struct alc_spec *spec = codec->spec;
11974 int err;
11975 static hda_nid_t alc268_ignore[] = { 0 };
11976
11977 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11978 alc268_ignore);
11979 if (err < 0)
11980 return err;
7e0e44d4
TI
11981 if (!spec->autocfg.line_outs) {
11982 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11983 spec->multiout.max_channels = 2;
11984 spec->no_analog = 1;
11985 goto dig_only;
11986 }
a361d84b 11987 return 0; /* can't find valid BIOS pin config */
7e0e44d4 11988 }
a361d84b
KY
11989 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11990 if (err < 0)
11991 return err;
11992 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11993 if (err < 0)
11994 return err;
11995
11996 spec->multiout.max_channels = 2;
11997
7e0e44d4 11998 dig_only:
a361d84b 11999 /* digital only support output */
7e0e44d4 12000 if (spec->autocfg.dig_outs) {
a361d84b 12001 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
12002 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12003 }
603c4019 12004 if (spec->kctls.list)
d88897ea 12005 add_mixer(spec, spec->kctls.list);
a361d84b 12006
892981ff 12007 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 12008 add_mixer(spec, alc268_beep_mixer);
aef9d318 12009
d88897ea 12010 add_verb(spec, alc268_volume_init_verbs);
a361d84b 12011 spec->num_mux_defs = 1;
61b9b9b1 12012 spec->input_mux = &spec->private_imux[0];
a361d84b 12013
776e184e
TI
12014 err = alc_auto_add_mic_boost(codec);
12015 if (err < 0)
12016 return err;
12017
a361d84b
KY
12018 return 1;
12019}
12020
12021#define alc268_auto_init_multi_out alc882_auto_init_multi_out
12022#define alc268_auto_init_hp_out alc882_auto_init_hp_out
12023#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12024
12025/* init callback for auto-configuration model -- overriding the default init */
12026static void alc268_auto_init(struct hda_codec *codec)
12027{
f6c7e546 12028 struct alc_spec *spec = codec->spec;
a361d84b
KY
12029 alc268_auto_init_multi_out(codec);
12030 alc268_auto_init_hp_out(codec);
12031 alc268_auto_init_mono_speaker_out(codec);
12032 alc268_auto_init_analog_input(codec);
f6c7e546 12033 if (spec->unsol_event)
7fb0d78f 12034 alc_inithook(codec);
a361d84b
KY
12035}
12036
12037/*
12038 * configuration and preset
12039 */
12040static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 12041 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 12042 [ALC268_3ST] = "3stack",
983f8ae4 12043 [ALC268_TOSHIBA] = "toshiba",
d273809e 12044 [ALC268_ACER] = "acer",
c238b4f4 12045 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 12046 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 12047 [ALC268_DELL] = "dell",
f12462c5 12048 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
12049#ifdef CONFIG_SND_DEBUG
12050 [ALC268_TEST] = "test",
12051#endif
a361d84b
KY
12052 [ALC268_AUTO] = "auto",
12053};
12054
12055static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 12056 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 12057 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 12058 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 12059 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 12060 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
12061 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12062 ALC268_ACER_ASPIRE_ONE),
3866f0b0 12063 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
57d13927 12064 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
ac3e3741 12065 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 12066 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 12067 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 12068 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
2346d0cd 12069 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
378bd6a5 12070 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 12071 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 12072 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
f12462c5 12073 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
12074 {}
12075};
12076
12077static struct alc_config_preset alc268_presets[] = {
eb5a6621 12078 [ALC267_QUANTA_IL1] = {
22971e3a 12079 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
eb5a6621
HRK
12080 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12081 alc267_quanta_il1_verbs },
12082 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12083 .dac_nids = alc268_dac_nids,
12084 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12085 .adc_nids = alc268_adc_nids_alt,
12086 .hp_nid = 0x03,
12087 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12088 .channel_mode = alc268_modes,
12089 .input_mux = &alc268_capture_source,
12090 .unsol_event = alc267_quanta_il1_unsol_event,
12091 .init_hook = alc267_quanta_il1_automute,
12092 },
a361d84b 12093 [ALC268_3ST] = {
aef9d318
TI
12094 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12095 alc268_beep_mixer },
a361d84b
KY
12096 .init_verbs = { alc268_base_init_verbs },
12097 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12098 .dac_nids = alc268_dac_nids,
12099 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12100 .adc_nids = alc268_adc_nids_alt,
e1406348 12101 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
12102 .hp_nid = 0x03,
12103 .dig_out_nid = ALC268_DIGOUT_NID,
12104 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12105 .channel_mode = alc268_modes,
12106 .input_mux = &alc268_capture_source,
12107 },
d1a991a6 12108 [ALC268_TOSHIBA] = {
aef9d318
TI
12109 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12110 alc268_beep_mixer },
d273809e
TI
12111 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12112 alc268_toshiba_verbs },
d1a991a6
KY
12113 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12114 .dac_nids = alc268_dac_nids,
12115 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12116 .adc_nids = alc268_adc_nids_alt,
e1406348 12117 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
12118 .hp_nid = 0x03,
12119 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12120 .channel_mode = alc268_modes,
12121 .input_mux = &alc268_capture_source,
d273809e
TI
12122 .unsol_event = alc268_toshiba_unsol_event,
12123 .init_hook = alc268_toshiba_automute,
12124 },
12125 [ALC268_ACER] = {
aef9d318
TI
12126 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12127 alc268_beep_mixer },
d273809e
TI
12128 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12129 alc268_acer_verbs },
12130 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12131 .dac_nids = alc268_dac_nids,
12132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12133 .adc_nids = alc268_adc_nids_alt,
e1406348 12134 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
12135 .hp_nid = 0x02,
12136 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12137 .channel_mode = alc268_modes,
0ccb541c 12138 .input_mux = &alc268_acer_capture_source,
d273809e 12139 .unsol_event = alc268_acer_unsol_event,
889c4395 12140 .init_hook = alc268_acer_init_hook,
d1a991a6 12141 },
c238b4f4
TI
12142 [ALC268_ACER_DMIC] = {
12143 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12144 alc268_beep_mixer },
12145 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12146 alc268_acer_verbs },
12147 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12148 .dac_nids = alc268_dac_nids,
12149 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12150 .adc_nids = alc268_adc_nids_alt,
12151 .capsrc_nids = alc268_capsrc_nids,
12152 .hp_nid = 0x02,
12153 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12154 .channel_mode = alc268_modes,
12155 .input_mux = &alc268_acer_dmic_capture_source,
12156 .unsol_event = alc268_acer_unsol_event,
12157 .init_hook = alc268_acer_init_hook,
12158 },
8ef355da
KY
12159 [ALC268_ACER_ASPIRE_ONE] = {
12160 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a
TI
12161 alc268_beep_mixer,
12162 alc268_capture_alt_mixer },
8ef355da
KY
12163 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12164 alc268_acer_aspire_one_verbs },
12165 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12166 .dac_nids = alc268_dac_nids,
12167 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12168 .adc_nids = alc268_adc_nids_alt,
12169 .capsrc_nids = alc268_capsrc_nids,
12170 .hp_nid = 0x03,
12171 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12172 .channel_mode = alc268_modes,
12173 .input_mux = &alc268_acer_lc_capture_source,
12174 .unsol_event = alc268_acer_lc_unsol_event,
12175 .init_hook = alc268_acer_lc_init_hook,
12176 },
3866f0b0 12177 [ALC268_DELL] = {
aef9d318 12178 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
12179 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12180 alc268_dell_verbs },
12181 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12182 .dac_nids = alc268_dac_nids,
12183 .hp_nid = 0x02,
12184 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12185 .channel_mode = alc268_modes,
12186 .unsol_event = alc268_dell_unsol_event,
12187 .init_hook = alc268_dell_init_hook,
12188 .input_mux = &alc268_capture_source,
12189 },
f12462c5 12190 [ALC268_ZEPTO] = {
aef9d318
TI
12191 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12192 alc268_beep_mixer },
f12462c5
MT
12193 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12194 alc268_toshiba_verbs },
12195 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12196 .dac_nids = alc268_dac_nids,
12197 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12198 .adc_nids = alc268_adc_nids_alt,
e1406348 12199 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
12200 .hp_nid = 0x03,
12201 .dig_out_nid = ALC268_DIGOUT_NID,
12202 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12203 .channel_mode = alc268_modes,
12204 .input_mux = &alc268_capture_source,
12205 .unsol_event = alc268_toshiba_unsol_event,
12206 .init_hook = alc268_toshiba_automute
12207 },
86c53bd2
JW
12208#ifdef CONFIG_SND_DEBUG
12209 [ALC268_TEST] = {
12210 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12211 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12212 alc268_volume_init_verbs },
12213 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12214 .dac_nids = alc268_dac_nids,
12215 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12216 .adc_nids = alc268_adc_nids_alt,
e1406348 12217 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
12218 .hp_nid = 0x03,
12219 .dig_out_nid = ALC268_DIGOUT_NID,
12220 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12221 .channel_mode = alc268_modes,
12222 .input_mux = &alc268_capture_source,
12223 },
12224#endif
a361d84b
KY
12225};
12226
12227static int patch_alc268(struct hda_codec *codec)
12228{
12229 struct alc_spec *spec;
12230 int board_config;
22971e3a 12231 int i, has_beep, err;
a361d84b
KY
12232
12233 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12234 if (spec == NULL)
12235 return -ENOMEM;
12236
12237 codec->spec = spec;
12238
12239 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12240 alc268_models,
12241 alc268_cfg_tbl);
12242
12243 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12244 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12245 "trying auto-probe from BIOS...\n");
12246 board_config = ALC268_AUTO;
12247 }
12248
12249 if (board_config == ALC268_AUTO) {
12250 /* automatic parse from the BIOS config */
12251 err = alc268_parse_auto_config(codec);
12252 if (err < 0) {
12253 alc_free(codec);
12254 return err;
12255 } else if (!err) {
12256 printk(KERN_INFO
12257 "hda_codec: Cannot set up configuration "
12258 "from BIOS. Using base mode...\n");
12259 board_config = ALC268_3ST;
12260 }
12261 }
12262
12263 if (board_config != ALC268_AUTO)
12264 setup_preset(spec, &alc268_presets[board_config]);
12265
2f893286
KY
12266 if (codec->vendor_id == 0x10ec0267) {
12267 spec->stream_name_analog = "ALC267 Analog";
12268 spec->stream_name_digital = "ALC267 Digital";
12269 } else {
12270 spec->stream_name_analog = "ALC268 Analog";
12271 spec->stream_name_digital = "ALC268 Digital";
12272 }
12273
a361d84b
KY
12274 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12275 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 12276 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 12277
a361d84b
KY
12278 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12279
22971e3a
TI
12280 has_beep = 0;
12281 for (i = 0; i < spec->num_mixers; i++) {
12282 if (spec->mixers[i] == alc268_beep_mixer) {
12283 has_beep = 1;
12284 break;
12285 }
12286 }
12287
12288 if (has_beep) {
12289 err = snd_hda_attach_beep_device(codec, 0x1);
12290 if (err < 0) {
12291 alc_free(codec);
12292 return err;
12293 }
12294 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12295 /* override the amp caps for beep generator */
12296 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
12297 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12298 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12299 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12300 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 12301 }
aef9d318 12302
7e0e44d4 12303 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
12304 /* check whether NID 0x07 is valid */
12305 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 12306 int i;
3866f0b0
TI
12307
12308 /* get type */
12309 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 12310 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
12311 spec->adc_nids = alc268_adc_nids_alt;
12312 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
d88897ea 12313 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
12314 } else {
12315 spec->adc_nids = alc268_adc_nids;
12316 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 12317 add_mixer(spec, alc268_capture_mixer);
a361d84b 12318 }
e1406348 12319 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
12320 /* set default input source */
12321 for (i = 0; i < spec->num_adc_nids; i++)
12322 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12323 0, AC_VERB_SET_CONNECT_SEL,
12324 spec->input_mux->items[0].index);
a361d84b 12325 }
2134ea4f
TI
12326
12327 spec->vmaster_nid = 0x02;
12328
a361d84b
KY
12329 codec->patch_ops = alc_patch_ops;
12330 if (board_config == ALC268_AUTO)
12331 spec->init_hook = alc268_auto_init;
ea1fb29a 12332
daead538
TI
12333 codec->proc_widget_hook = print_realtek_coef;
12334
a361d84b
KY
12335 return 0;
12336}
12337
f6a92248
KY
12338/*
12339 * ALC269 channel source setting (2 channel)
12340 */
12341#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12342
12343#define alc269_dac_nids alc260_dac_nids
12344
12345static hda_nid_t alc269_adc_nids[1] = {
12346 /* ADC1 */
f53281e6
KY
12347 0x08,
12348};
12349
e01bf509
TI
12350static hda_nid_t alc269_capsrc_nids[1] = {
12351 0x23,
12352};
12353
12354/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12355 * not a mux!
12356 */
12357
f53281e6
KY
12358static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12359 .num_items = 2,
12360 .items = {
12361 { "i-Mic", 0x5 },
12362 { "e-Mic", 0x0 },
12363 },
12364};
12365
12366static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12367 .num_items = 2,
12368 .items = {
12369 { "i-Mic", 0x1 },
12370 { "e-Mic", 0x0 },
12371 },
f6a92248
KY
12372};
12373
12374#define alc269_modes alc260_modes
12375#define alc269_capture_source alc880_lg_lw_capture_source
12376
12377static struct snd_kcontrol_new alc269_base_mixer[] = {
12378 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12379 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12384 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12387 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12388 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12389 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12390 { } /* end */
12391};
12392
60db6b53
KY
12393static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12394 /* output mixer control */
12395 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12396 {
12397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12398 .name = "Master Playback Switch",
12399 .info = snd_hda_mixer_amp_switch_info,
12400 .get = snd_hda_mixer_amp_switch_get,
12401 .put = alc268_acer_master_sw_put,
12402 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12403 },
12404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12406 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12408 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12409 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
12410 { }
12411};
12412
64154835
TV
12413static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12414 /* output mixer control */
12415 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12416 {
12417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12418 .name = "Master Playback Switch",
12419 .info = snd_hda_mixer_amp_switch_info,
12420 .get = snd_hda_mixer_amp_switch_get,
12421 .put = alc268_acer_master_sw_put,
12422 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12423 },
12424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12426 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12427 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12428 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12429 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12430 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12431 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
12433 { }
12434};
12435
f53281e6
KY
12436/* bind volumes of both NID 0x0c and 0x0d */
12437static struct hda_bind_ctls alc269_epc_bind_vol = {
12438 .ops = &snd_hda_bind_vol,
12439 .values = {
12440 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12441 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12442 0
12443 },
12444};
12445
12446static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12447 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12448 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12449 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12450 { } /* end */
12451};
12452
f53281e6
KY
12453/* capture mixer elements */
12454static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12455 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12456 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
12457 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12458 { } /* end */
12459};
12460
12461/* FSC amilo */
12462static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12463 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12465 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
f53281e6
KY
12466 { } /* end */
12467};
12468
60db6b53
KY
12469static struct hda_verb alc269_quanta_fl1_verbs[] = {
12470 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12471 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12474 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12475 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12476 { }
12477};
f6a92248 12478
64154835
TV
12479static struct hda_verb alc269_lifebook_verbs[] = {
12480 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12482 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12484 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12485 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12486 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12487 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12488 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12489 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12490 { }
12491};
12492
60db6b53
KY
12493/* toggle speaker-output according to the hp-jack state */
12494static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12495{
12496 unsigned int present;
12497 unsigned char bits;
f6a92248 12498
60db6b53
KY
12499 present = snd_hda_codec_read(codec, 0x15, 0,
12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12501 bits = present ? AMP_IN_MUTE(0) : 0;
12502 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12503 AMP_IN_MUTE(0), bits);
12504 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12505 AMP_IN_MUTE(0), bits);
f6a92248 12506
60db6b53
KY
12507 snd_hda_codec_write(codec, 0x20, 0,
12508 AC_VERB_SET_COEF_INDEX, 0x0c);
12509 snd_hda_codec_write(codec, 0x20, 0,
12510 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 12511
60db6b53
KY
12512 snd_hda_codec_write(codec, 0x20, 0,
12513 AC_VERB_SET_COEF_INDEX, 0x0c);
12514 snd_hda_codec_write(codec, 0x20, 0,
12515 AC_VERB_SET_PROC_COEF, 0x480);
12516}
f6a92248 12517
64154835
TV
12518/* toggle speaker-output according to the hp-jacks state */
12519static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12520{
12521 unsigned int present;
12522 unsigned char bits;
12523
12524 /* Check laptop headphone socket */
12525 present = snd_hda_codec_read(codec, 0x15, 0,
12526 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12527
12528 /* Check port replicator headphone socket */
12529 present |= snd_hda_codec_read(codec, 0x1a, 0,
12530 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12531
12532 bits = present ? AMP_IN_MUTE(0) : 0;
12533 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12534 AMP_IN_MUTE(0), bits);
12535 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12536 AMP_IN_MUTE(0), bits);
12537
12538 snd_hda_codec_write(codec, 0x20, 0,
12539 AC_VERB_SET_COEF_INDEX, 0x0c);
12540 snd_hda_codec_write(codec, 0x20, 0,
12541 AC_VERB_SET_PROC_COEF, 0x680);
12542
12543 snd_hda_codec_write(codec, 0x20, 0,
12544 AC_VERB_SET_COEF_INDEX, 0x0c);
12545 snd_hda_codec_write(codec, 0x20, 0,
12546 AC_VERB_SET_PROC_COEF, 0x480);
12547}
12548
60db6b53
KY
12549static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12550{
12551 unsigned int present;
f6a92248 12552
60db6b53
KY
12553 present = snd_hda_codec_read(codec, 0x18, 0,
12554 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12555 snd_hda_codec_write(codec, 0x23, 0,
12556 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12557}
f6a92248 12558
64154835
TV
12559static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12560{
12561 unsigned int present_laptop;
12562 unsigned int present_dock;
12563
12564 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12565 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12566
12567 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12568 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12569
12570 /* Laptop mic port overrides dock mic port, design decision */
12571 if (present_dock)
12572 snd_hda_codec_write(codec, 0x23, 0,
12573 AC_VERB_SET_CONNECT_SEL, 0x3);
12574 if (present_laptop)
12575 snd_hda_codec_write(codec, 0x23, 0,
12576 AC_VERB_SET_CONNECT_SEL, 0x0);
12577 if (!present_dock && !present_laptop)
12578 snd_hda_codec_write(codec, 0x23, 0,
12579 AC_VERB_SET_CONNECT_SEL, 0x1);
12580}
12581
60db6b53
KY
12582static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12583 unsigned int res)
12584{
12585 if ((res >> 26) == ALC880_HP_EVENT)
12586 alc269_quanta_fl1_speaker_automute(codec);
12587 if ((res >> 26) == ALC880_MIC_EVENT)
12588 alc269_quanta_fl1_mic_automute(codec);
12589}
f6a92248 12590
64154835
TV
12591static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12592 unsigned int res)
12593{
12594 if ((res >> 26) == ALC880_HP_EVENT)
12595 alc269_lifebook_speaker_automute(codec);
12596 if ((res >> 26) == ALC880_MIC_EVENT)
12597 alc269_lifebook_mic_autoswitch(codec);
12598}
12599
60db6b53
KY
12600static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12601{
12602 alc269_quanta_fl1_speaker_automute(codec);
12603 alc269_quanta_fl1_mic_automute(codec);
12604}
f6a92248 12605
64154835
TV
12606static void alc269_lifebook_init_hook(struct hda_codec *codec)
12607{
12608 alc269_lifebook_speaker_automute(codec);
12609 alc269_lifebook_mic_autoswitch(codec);
12610}
12611
f53281e6
KY
12612static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12613 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12614 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12615 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12617 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12618 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12619 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12620 {}
12621};
12622
12623static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12625 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12627 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12628 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12629 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12630 {}
12631};
12632
12633/* toggle speaker-output according to the hp-jack state */
12634static void alc269_speaker_automute(struct hda_codec *codec)
12635{
12636 unsigned int present;
60db6b53 12637 unsigned char bits;
f53281e6
KY
12638
12639 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 12640 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
12641 bits = present ? AMP_IN_MUTE(0) : 0;
12642 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 12643 AMP_IN_MUTE(0), bits);
f53281e6 12644 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 12645 AMP_IN_MUTE(0), bits);
f53281e6
KY
12646}
12647
12648static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12649{
12650 unsigned int present;
12651
60db6b53
KY
12652 present = snd_hda_codec_read(codec, 0x18, 0,
12653 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12654 snd_hda_codec_write(codec, 0x23, 0,
12655 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
12656}
12657
12658static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12659{
12660 unsigned int present;
12661
60db6b53
KY
12662 present = snd_hda_codec_read(codec, 0x18, 0,
12663 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 12664 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12665 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 12666 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12667 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
12668}
12669
12670/* unsolicited event for HP jack sensing */
12671static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 12672 unsigned int res)
f53281e6
KY
12673{
12674 if ((res >> 26) == ALC880_HP_EVENT)
12675 alc269_speaker_automute(codec);
12676
12677 if ((res >> 26) == ALC880_MIC_EVENT)
12678 alc269_eeepc_dmic_automute(codec);
12679}
12680
12681static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12682{
12683 alc269_speaker_automute(codec);
12684 alc269_eeepc_dmic_automute(codec);
12685}
12686
12687/* unsolicited event for HP jack sensing */
12688static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 12689 unsigned int res)
f53281e6
KY
12690{
12691 if ((res >> 26) == ALC880_HP_EVENT)
12692 alc269_speaker_automute(codec);
12693
12694 if ((res >> 26) == ALC880_MIC_EVENT)
12695 alc269_eeepc_amic_automute(codec);
12696}
12697
12698static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12699{
12700 alc269_speaker_automute(codec);
12701 alc269_eeepc_amic_automute(codec);
12702}
12703
60db6b53
KY
12704/*
12705 * generic initialization of ADC, input mixers and output mixers
12706 */
12707static struct hda_verb alc269_init_verbs[] = {
12708 /*
12709 * Unmute ADC0 and set the default input to mic-in
12710 */
12711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12712
12713 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12714 * analog-loopback mixer widget
12715 * Note: PASD motherboards uses the Line In 2 as the input for
12716 * front panel mic (mic 2)
12717 */
12718 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12724
12725 /*
12726 * Set up output mixers (0x0c - 0x0e)
12727 */
12728 /* set vol=0 to output mixers */
12729 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12730 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12731
12732 /* set up input amps for analog loopback */
12733 /* Amp Indices: DAC = 0, mixer = 1 */
12734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740
12741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12743 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12744 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12747 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12748
12749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12753 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12756
12757 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12758 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12759
12760 /* FIXME: use matrix-type input source selection */
12761 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12762 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12767
12768 /* set EAPD */
12769 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12770 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12771 { }
12772};
12773
f6a92248
KY
12774/* add playback controls from the parsed DAC table */
12775static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12776 const struct auto_pin_cfg *cfg)
12777{
12778 hda_nid_t nid;
12779 int err;
12780
12781 spec->multiout.num_dacs = 1; /* only use one dac */
12782 spec->multiout.dac_nids = spec->private_dac_nids;
12783 spec->multiout.dac_nids[0] = 2;
12784
12785 nid = cfg->line_out_pins[0];
12786 if (nid) {
12787 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12788 "Front Playback Volume",
12789 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12790 if (err < 0)
12791 return err;
12792 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12793 "Front Playback Switch",
12794 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12795 if (err < 0)
12796 return err;
12797 }
12798
12799 nid = cfg->speaker_pins[0];
12800 if (nid) {
12801 if (!cfg->line_out_pins[0]) {
12802 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12803 "Speaker Playback Volume",
12804 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12805 HDA_OUTPUT));
12806 if (err < 0)
12807 return err;
12808 }
12809 if (nid == 0x16) {
12810 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12811 "Speaker Playback Switch",
12812 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12813 HDA_OUTPUT));
12814 if (err < 0)
12815 return err;
12816 } else {
12817 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12818 "Speaker Playback Switch",
12819 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12820 HDA_OUTPUT));
12821 if (err < 0)
12822 return err;
12823 }
12824 }
12825 nid = cfg->hp_pins[0];
12826 if (nid) {
12827 /* spec->multiout.hp_nid = 2; */
12828 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12829 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12830 "Headphone Playback Volume",
12831 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12832 HDA_OUTPUT));
12833 if (err < 0)
12834 return err;
12835 }
12836 if (nid == 0x16) {
12837 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12838 "Headphone Playback Switch",
12839 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12840 HDA_OUTPUT));
12841 if (err < 0)
12842 return err;
12843 } else {
12844 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12845 "Headphone Playback Switch",
12846 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12847 HDA_OUTPUT));
12848 if (err < 0)
12849 return err;
12850 }
12851 }
12852 return 0;
12853}
12854
ee956e09
TI
12855static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12856 const struct auto_pin_cfg *cfg)
12857{
12858 int err;
12859
12860 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12861 if (err < 0)
12862 return err;
12863 /* digital-mic input pin is excluded in alc880_auto_create..()
12864 * because it's under 0x18
12865 */
12866 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12867 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
61b9b9b1 12868 struct hda_input_mux *imux = &spec->private_imux[0];
ee956e09
TI
12869 imux->items[imux->num_items].label = "Int Mic";
12870 imux->items[imux->num_items].index = 0x05;
12871 imux->num_items++;
12872 }
12873 return 0;
12874}
f6a92248
KY
12875
12876#ifdef CONFIG_SND_HDA_POWER_SAVE
12877#define alc269_loopbacks alc880_loopbacks
12878#endif
12879
12880/* pcm configuration: identiacal with ALC880 */
12881#define alc269_pcm_analog_playback alc880_pcm_analog_playback
12882#define alc269_pcm_analog_capture alc880_pcm_analog_capture
12883#define alc269_pcm_digital_playback alc880_pcm_digital_playback
12884#define alc269_pcm_digital_capture alc880_pcm_digital_capture
12885
f03d3115
TI
12886static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12887 .substreams = 1,
12888 .channels_min = 2,
12889 .channels_max = 8,
12890 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12891 /* NID is set in alc_build_pcms */
12892 .ops = {
12893 .open = alc880_playback_pcm_open,
12894 .prepare = alc880_playback_pcm_prepare,
12895 .cleanup = alc880_playback_pcm_cleanup
12896 },
12897};
12898
12899static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12900 .substreams = 1,
12901 .channels_min = 2,
12902 .channels_max = 2,
12903 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12904 /* NID is set in alc_build_pcms */
12905};
12906
f6a92248
KY
12907/*
12908 * BIOS auto configuration
12909 */
12910static int alc269_parse_auto_config(struct hda_codec *codec)
12911{
12912 struct alc_spec *spec = codec->spec;
cfb9fb55 12913 int err;
f6a92248
KY
12914 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12915
12916 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12917 alc269_ignore);
12918 if (err < 0)
12919 return err;
12920
12921 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12922 if (err < 0)
12923 return err;
12924 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12925 if (err < 0)
12926 return err;
12927
12928 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12929
0852d7a6 12930 if (spec->autocfg.dig_outs)
f6a92248
KY
12931 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12932
603c4019 12933 if (spec->kctls.list)
d88897ea 12934 add_mixer(spec, spec->kctls.list);
f6a92248 12935
d88897ea 12936 add_verb(spec, alc269_init_verbs);
f6a92248 12937 spec->num_mux_defs = 1;
61b9b9b1 12938 spec->input_mux = &spec->private_imux[0];
e01bf509
TI
12939 /* set default input source */
12940 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12941 0, AC_VERB_SET_CONNECT_SEL,
12942 spec->input_mux->items[0].index);
f6a92248
KY
12943
12944 err = alc_auto_add_mic_boost(codec);
12945 if (err < 0)
12946 return err;
12947
7e0e44d4 12948 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 12949 set_capture_mixer(spec);
f53281e6 12950
f6a92248
KY
12951 return 1;
12952}
12953
12954#define alc269_auto_init_multi_out alc882_auto_init_multi_out
12955#define alc269_auto_init_hp_out alc882_auto_init_hp_out
12956#define alc269_auto_init_analog_input alc882_auto_init_analog_input
12957
12958
12959/* init callback for auto-configuration model -- overriding the default init */
12960static void alc269_auto_init(struct hda_codec *codec)
12961{
f6c7e546 12962 struct alc_spec *spec = codec->spec;
f6a92248
KY
12963 alc269_auto_init_multi_out(codec);
12964 alc269_auto_init_hp_out(codec);
12965 alc269_auto_init_analog_input(codec);
f6c7e546 12966 if (spec->unsol_event)
7fb0d78f 12967 alc_inithook(codec);
f6a92248
KY
12968}
12969
12970/*
12971 * configuration and preset
12972 */
12973static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 12974 [ALC269_BASIC] = "basic",
2922c9af
TI
12975 [ALC269_QUANTA_FL1] = "quanta",
12976 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
26f5df26 12977 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
64154835
TV
12978 [ALC269_FUJITSU] = "fujitsu",
12979 [ALC269_LIFEBOOK] = "lifebook"
f6a92248
KY
12980};
12981
12982static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 12983 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
12984 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12985 ALC269_ASUS_EEEPC_P703),
622e84cd
KY
12986 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12987 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12988 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12989 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12990 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12991 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
f53281e6
KY
12992 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12993 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
12994 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12995 ALC269_ASUS_EEEPC_P901),
622e84cd 12996 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
26f5df26 12997 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
64154835 12998 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
f6a92248
KY
12999 {}
13000};
13001
13002static struct alc_config_preset alc269_presets[] = {
13003 [ALC269_BASIC] = {
f9e336f6 13004 .mixers = { alc269_base_mixer },
f6a92248
KY
13005 .init_verbs = { alc269_init_verbs },
13006 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13007 .dac_nids = alc269_dac_nids,
13008 .hp_nid = 0x03,
13009 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13010 .channel_mode = alc269_modes,
13011 .input_mux = &alc269_capture_source,
13012 },
60db6b53
KY
13013 [ALC269_QUANTA_FL1] = {
13014 .mixers = { alc269_quanta_fl1_mixer },
13015 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13016 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13017 .dac_nids = alc269_dac_nids,
13018 .hp_nid = 0x03,
13019 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13020 .channel_mode = alc269_modes,
13021 .input_mux = &alc269_capture_source,
13022 .unsol_event = alc269_quanta_fl1_unsol_event,
13023 .init_hook = alc269_quanta_fl1_init_hook,
13024 },
f53281e6 13025 [ALC269_ASUS_EEEPC_P703] = {
f9e336f6
TI
13026 .mixers = { alc269_eeepc_mixer },
13027 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13028 .init_verbs = { alc269_init_verbs,
13029 alc269_eeepc_amic_init_verbs },
13030 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13031 .dac_nids = alc269_dac_nids,
13032 .hp_nid = 0x03,
13033 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13034 .channel_mode = alc269_modes,
13035 .input_mux = &alc269_eeepc_amic_capture_source,
13036 .unsol_event = alc269_eeepc_amic_unsol_event,
13037 .init_hook = alc269_eeepc_amic_inithook,
13038 },
13039 [ALC269_ASUS_EEEPC_P901] = {
f9e336f6
TI
13040 .mixers = { alc269_eeepc_mixer },
13041 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13042 .init_verbs = { alc269_init_verbs,
13043 alc269_eeepc_dmic_init_verbs },
13044 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13045 .dac_nids = alc269_dac_nids,
13046 .hp_nid = 0x03,
13047 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13048 .channel_mode = alc269_modes,
13049 .input_mux = &alc269_eeepc_dmic_capture_source,
13050 .unsol_event = alc269_eeepc_dmic_unsol_event,
13051 .init_hook = alc269_eeepc_dmic_inithook,
13052 },
26f5df26 13053 [ALC269_FUJITSU] = {
45bdd1c1 13054 .mixers = { alc269_fujitsu_mixer },
26f5df26
TI
13055 .cap_mixer = alc269_epc_capture_mixer,
13056 .init_verbs = { alc269_init_verbs,
13057 alc269_eeepc_dmic_init_verbs },
13058 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13059 .dac_nids = alc269_dac_nids,
13060 .hp_nid = 0x03,
13061 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13062 .channel_mode = alc269_modes,
13063 .input_mux = &alc269_eeepc_dmic_capture_source,
13064 .unsol_event = alc269_eeepc_dmic_unsol_event,
13065 .init_hook = alc269_eeepc_dmic_inithook,
13066 },
64154835
TV
13067 [ALC269_LIFEBOOK] = {
13068 .mixers = { alc269_lifebook_mixer },
13069 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13070 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13071 .dac_nids = alc269_dac_nids,
13072 .hp_nid = 0x03,
13073 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13074 .channel_mode = alc269_modes,
13075 .input_mux = &alc269_capture_source,
13076 .unsol_event = alc269_lifebook_unsol_event,
13077 .init_hook = alc269_lifebook_init_hook,
13078 },
f6a92248
KY
13079};
13080
13081static int patch_alc269(struct hda_codec *codec)
13082{
13083 struct alc_spec *spec;
13084 int board_config;
13085 int err;
13086
13087 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13088 if (spec == NULL)
13089 return -ENOMEM;
13090
13091 codec->spec = spec;
13092
2c3bf9ab
TI
13093 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13094
f6a92248
KY
13095 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13096 alc269_models,
13097 alc269_cfg_tbl);
13098
13099 if (board_config < 0) {
13100 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
13101 "trying auto-probe from BIOS...\n");
13102 board_config = ALC269_AUTO;
13103 }
13104
13105 if (board_config == ALC269_AUTO) {
13106 /* automatic parse from the BIOS config */
13107 err = alc269_parse_auto_config(codec);
13108 if (err < 0) {
13109 alc_free(codec);
13110 return err;
13111 } else if (!err) {
13112 printk(KERN_INFO
13113 "hda_codec: Cannot set up configuration "
13114 "from BIOS. Using base mode...\n");
13115 board_config = ALC269_BASIC;
13116 }
13117 }
13118
680cd536
KK
13119 err = snd_hda_attach_beep_device(codec, 0x1);
13120 if (err < 0) {
13121 alc_free(codec);
13122 return err;
13123 }
13124
f6a92248
KY
13125 if (board_config != ALC269_AUTO)
13126 setup_preset(spec, &alc269_presets[board_config]);
13127
13128 spec->stream_name_analog = "ALC269 Analog";
f03d3115
TI
13129 if (codec->subsystem_id == 0x17aa3bf8) {
13130 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13131 * fix the sample rate of analog I/O to 44.1kHz
13132 */
13133 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13134 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13135 } else {
13136 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13137 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13138 }
f6a92248
KY
13139 spec->stream_name_digital = "ALC269 Digital";
13140 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13141 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13142
13143 spec->adc_nids = alc269_adc_nids;
13144 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 13145 spec->capsrc_nids = alc269_capsrc_nids;
f9e336f6
TI
13146 if (!spec->cap_mixer)
13147 set_capture_mixer(spec);
45bdd1c1 13148 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248
KY
13149
13150 codec->patch_ops = alc_patch_ops;
13151 if (board_config == ALC269_AUTO)
13152 spec->init_hook = alc269_auto_init;
13153#ifdef CONFIG_SND_HDA_POWER_SAVE
13154 if (!spec->loopback.amplist)
13155 spec->loopback.amplist = alc269_loopbacks;
13156#endif
daead538 13157 codec->proc_widget_hook = print_realtek_coef;
f6a92248
KY
13158
13159 return 0;
13160}
13161
df694daa
KY
13162/*
13163 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13164 */
13165
13166/*
13167 * set the path ways for 2 channel output
13168 * need to set the codec line out and mic 1 pin widgets to inputs
13169 */
13170static struct hda_verb alc861_threestack_ch2_init[] = {
13171 /* set pin widget 1Ah (line in) for input */
13172 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13173 /* set pin widget 18h (mic1/2) for input, for mic also enable
13174 * the vref
13175 */
df694daa
KY
13176 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13177
9c7f852e
TI
13178 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13179#if 0
13180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13181 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13182#endif
df694daa
KY
13183 { } /* end */
13184};
13185/*
13186 * 6ch mode
13187 * need to set the codec line out and mic 1 pin widgets to outputs
13188 */
13189static struct hda_verb alc861_threestack_ch6_init[] = {
13190 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13191 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13192 /* set pin widget 18h (mic1) for output (CLFE)*/
13193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13194
13195 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 13196 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 13197
9c7f852e
TI
13198 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13199#if 0
13200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13201 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13202#endif
df694daa
KY
13203 { } /* end */
13204};
13205
13206static struct hda_channel_mode alc861_threestack_modes[2] = {
13207 { 2, alc861_threestack_ch2_init },
13208 { 6, alc861_threestack_ch6_init },
13209};
22309c3e
TI
13210/* Set mic1 as input and unmute the mixer */
13211static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13212 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13213 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13214 { } /* end */
13215};
13216/* Set mic1 as output and mute mixer */
13217static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13218 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13219 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13220 { } /* end */
13221};
13222
13223static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13224 { 2, alc861_uniwill_m31_ch2_init },
13225 { 4, alc861_uniwill_m31_ch4_init },
13226};
df694daa 13227
7cdbff94
MD
13228/* Set mic1 and line-in as input and unmute the mixer */
13229static struct hda_verb alc861_asus_ch2_init[] = {
13230 /* set pin widget 1Ah (line in) for input */
13231 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13232 /* set pin widget 18h (mic1/2) for input, for mic also enable
13233 * the vref
13234 */
7cdbff94
MD
13235 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13236
13237 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13238#if 0
13239 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13240 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13241#endif
13242 { } /* end */
13243};
13244/* Set mic1 nad line-in as output and mute mixer */
13245static struct hda_verb alc861_asus_ch6_init[] = {
13246 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13247 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13248 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13249 /* set pin widget 18h (mic1) for output (CLFE)*/
13250 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13251 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13252 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13253 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13254
13255 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13256#if 0
13257 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13258 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13259#endif
13260 { } /* end */
13261};
13262
13263static struct hda_channel_mode alc861_asus_modes[2] = {
13264 { 2, alc861_asus_ch2_init },
13265 { 6, alc861_asus_ch6_init },
13266};
13267
df694daa
KY
13268/* patch-ALC861 */
13269
13270static struct snd_kcontrol_new alc861_base_mixer[] = {
13271 /* output mixer control */
13272 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13273 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13274 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13275 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13276 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13277
13278 /*Input mixer control */
13279 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13280 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13281 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13282 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13283 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13284 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13286 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13287 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13288 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13289
df694daa
KY
13290 { } /* end */
13291};
13292
13293static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13294 /* output mixer control */
13295 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13298 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13299 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13300
13301 /* Input mixer control */
13302 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13303 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13304 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13305 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13306 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13307 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13309 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13310 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13312
df694daa
KY
13313 {
13314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13315 .name = "Channel Mode",
13316 .info = alc_ch_mode_info,
13317 .get = alc_ch_mode_get,
13318 .put = alc_ch_mode_put,
13319 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13320 },
13321 { } /* end */
a53d1aec
TD
13322};
13323
d1d985f0 13324static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
13325 /* output mixer control */
13326 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13328 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 13329
a53d1aec 13330 { } /* end */
f12ab1e0 13331};
a53d1aec 13332
22309c3e
TI
13333static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13334 /* output mixer control */
13335 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13336 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13337 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13338 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13339 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13340
13341 /* Input mixer control */
13342 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13343 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13344 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13345 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13346 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13347 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13349 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13350 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13352
22309c3e
TI
13353 {
13354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13355 .name = "Channel Mode",
13356 .info = alc_ch_mode_info,
13357 .get = alc_ch_mode_get,
13358 .put = alc_ch_mode_put,
13359 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13360 },
13361 { } /* end */
f12ab1e0 13362};
7cdbff94
MD
13363
13364static struct snd_kcontrol_new alc861_asus_mixer[] = {
13365 /* output mixer control */
13366 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13368 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13369 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13370 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13371
13372 /* Input mixer control */
13373 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13374 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13375 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13376 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13377 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13378 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13380 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13381 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
13382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13383
7cdbff94
MD
13384 {
13385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13386 .name = "Channel Mode",
13387 .info = alc_ch_mode_info,
13388 .get = alc_ch_mode_get,
13389 .put = alc_ch_mode_put,
13390 .private_value = ARRAY_SIZE(alc861_asus_modes),
13391 },
13392 { }
56bb0cab
TI
13393};
13394
13395/* additional mixer */
d1d985f0 13396static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
13397 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13398 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
13399 { }
13400};
7cdbff94 13401
df694daa
KY
13402/*
13403 * generic initialization of ADC, input mixers and output mixers
13404 */
13405static struct hda_verb alc861_base_init_verbs[] = {
13406 /*
13407 * Unmute ADC0 and set the default input to mic-in
13408 */
13409 /* port-A for surround (rear panel) */
13410 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13411 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13412 /* port-B for mic-in (rear panel) with vref */
13413 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13414 /* port-C for line-in (rear panel) */
13415 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13416 /* port-D for Front */
13417 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13418 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13419 /* port-E for HP out (front panel) */
13420 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13421 /* route front PCM to HP */
9dece1d7 13422 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13423 /* port-F for mic-in (front panel) with vref */
13424 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13425 /* port-G for CLFE (rear panel) */
13426 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13427 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13428 /* port-H for side (rear panel) */
13429 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13430 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13431 /* CD-in */
13432 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13433 /* route front mic to ADC1*/
13434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13436
df694daa
KY
13437 /* Unmute DAC0~3 & spdif out*/
13438 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13439 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13440 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13441 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13442 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13443
df694daa
KY
13444 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13445 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13446 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13447 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13449
df694daa
KY
13450 /* Unmute Stereo Mixer 15 */
13451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13455
13456 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13462 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13463 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13464 /* hp used DAC 3 (Front) */
13465 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13466 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13467
13468 { }
13469};
13470
13471static struct hda_verb alc861_threestack_init_verbs[] = {
13472 /*
13473 * Unmute ADC0 and set the default input to mic-in
13474 */
13475 /* port-A for surround (rear panel) */
13476 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13477 /* port-B for mic-in (rear panel) with vref */
13478 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13479 /* port-C for line-in (rear panel) */
13480 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13481 /* port-D for Front */
13482 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13483 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13484 /* port-E for HP out (front panel) */
13485 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13486 /* route front PCM to HP */
9dece1d7 13487 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13488 /* port-F for mic-in (front panel) with vref */
13489 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13490 /* port-G for CLFE (rear panel) */
13491 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13492 /* port-H for side (rear panel) */
13493 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13494 /* CD-in */
13495 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13496 /* route front mic to ADC1*/
13497 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13498 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499 /* Unmute DAC0~3 & spdif out*/
13500 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13501 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13502 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13503 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13505
df694daa
KY
13506 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13507 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13508 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13509 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13510 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13511
df694daa
KY
13512 /* Unmute Stereo Mixer 15 */
13513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13514 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13517
13518 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13520 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13521 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13522 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13525 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13526 /* hp used DAC 3 (Front) */
13527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13529 { }
13530};
22309c3e
TI
13531
13532static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13533 /*
13534 * Unmute ADC0 and set the default input to mic-in
13535 */
13536 /* port-A for surround (rear panel) */
13537 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13538 /* port-B for mic-in (rear panel) with vref */
13539 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13540 /* port-C for line-in (rear panel) */
13541 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13542 /* port-D for Front */
13543 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13544 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13545 /* port-E for HP out (front panel) */
f12ab1e0
TI
13546 /* this has to be set to VREF80 */
13547 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 13548 /* route front PCM to HP */
9dece1d7 13549 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
13550 /* port-F for mic-in (front panel) with vref */
13551 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13552 /* port-G for CLFE (rear panel) */
13553 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13554 /* port-H for side (rear panel) */
13555 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13556 /* CD-in */
13557 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13558 /* route front mic to ADC1*/
13559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13560 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13561 /* Unmute DAC0~3 & spdif out*/
13562 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13563 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13564 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13565 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13567
22309c3e
TI
13568 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13569 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13570 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13571 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13572 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13573
22309c3e
TI
13574 /* Unmute Stereo Mixer 15 */
13575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
13579
13580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13581 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13583 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13588 /* hp used DAC 3 (Front) */
13589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
13590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13591 { }
13592};
13593
7cdbff94
MD
13594static struct hda_verb alc861_asus_init_verbs[] = {
13595 /*
13596 * Unmute ADC0 and set the default input to mic-in
13597 */
f12ab1e0
TI
13598 /* port-A for surround (rear panel)
13599 * according to codec#0 this is the HP jack
13600 */
7cdbff94
MD
13601 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13602 /* route front PCM to HP */
13603 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13604 /* port-B for mic-in (rear panel) with vref */
13605 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13606 /* port-C for line-in (rear panel) */
13607 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13608 /* port-D for Front */
13609 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13610 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13611 /* port-E for HP out (front panel) */
f12ab1e0
TI
13612 /* this has to be set to VREF80 */
13613 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 13614 /* route front PCM to HP */
9dece1d7 13615 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
13616 /* port-F for mic-in (front panel) with vref */
13617 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13618 /* port-G for CLFE (rear panel) */
13619 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13620 /* port-H for side (rear panel) */
13621 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13622 /* CD-in */
13623 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13624 /* route front mic to ADC1*/
13625 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13626 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13627 /* Unmute DAC0~3 & spdif out*/
13628 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13629 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13630 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13631 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13632 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13633 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13634 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13635 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13636 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13637 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13638
7cdbff94
MD
13639 /* Unmute Stereo Mixer 15 */
13640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13644
13645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13646 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13648 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13650 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13652 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13653 /* hp used DAC 3 (Front) */
13654 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13656 { }
13657};
13658
56bb0cab
TI
13659/* additional init verbs for ASUS laptops */
13660static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13661 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13662 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13663 { }
13664};
7cdbff94 13665
df694daa
KY
13666/*
13667 * generic initialization of ADC, input mixers and output mixers
13668 */
13669static struct hda_verb alc861_auto_init_verbs[] = {
13670 /*
13671 * Unmute ADC0 and set the default input to mic-in
13672 */
f12ab1e0 13673 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13675
df694daa
KY
13676 /* Unmute DAC0~3 & spdif out*/
13677 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13678 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13679 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13680 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13682
df694daa
KY
13683 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13684 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13685 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13686 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13687 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13688
df694daa
KY
13689 /* Unmute Stereo Mixer 15 */
13690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13694
13695 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13696 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13697 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13698 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13701 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13703
13704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13705 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13706 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13708 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13709 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13711 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 13712
f12ab1e0 13713 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
13714
13715 { }
13716};
13717
a53d1aec
TD
13718static struct hda_verb alc861_toshiba_init_verbs[] = {
13719 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 13720
a53d1aec
TD
13721 { }
13722};
13723
13724/* toggle speaker-output according to the hp-jack state */
13725static void alc861_toshiba_automute(struct hda_codec *codec)
13726{
13727 unsigned int present;
13728
13729 present = snd_hda_codec_read(codec, 0x0f, 0,
13730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13731 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13732 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13733 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13734 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
13735}
13736
13737static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13738 unsigned int res)
13739{
a53d1aec
TD
13740 if ((res >> 26) == ALC880_HP_EVENT)
13741 alc861_toshiba_automute(codec);
13742}
13743
df694daa
KY
13744/* pcm configuration: identiacal with ALC880 */
13745#define alc861_pcm_analog_playback alc880_pcm_analog_playback
13746#define alc861_pcm_analog_capture alc880_pcm_analog_capture
13747#define alc861_pcm_digital_playback alc880_pcm_digital_playback
13748#define alc861_pcm_digital_capture alc880_pcm_digital_capture
13749
13750
13751#define ALC861_DIGOUT_NID 0x07
13752
13753static struct hda_channel_mode alc861_8ch_modes[1] = {
13754 { 8, NULL }
13755};
13756
13757static hda_nid_t alc861_dac_nids[4] = {
13758 /* front, surround, clfe, side */
13759 0x03, 0x06, 0x05, 0x04
13760};
13761
9c7f852e
TI
13762static hda_nid_t alc660_dac_nids[3] = {
13763 /* front, clfe, surround */
13764 0x03, 0x05, 0x06
13765};
13766
df694daa
KY
13767static hda_nid_t alc861_adc_nids[1] = {
13768 /* ADC0-2 */
13769 0x08,
13770};
13771
13772static struct hda_input_mux alc861_capture_source = {
13773 .num_items = 5,
13774 .items = {
13775 { "Mic", 0x0 },
13776 { "Front Mic", 0x3 },
13777 { "Line", 0x1 },
13778 { "CD", 0x4 },
13779 { "Mixer", 0x5 },
13780 },
13781};
13782
13783/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
13784static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13785 const struct auto_pin_cfg *cfg)
df694daa
KY
13786{
13787 int i;
13788 hda_nid_t nid;
13789
13790 spec->multiout.dac_nids = spec->private_dac_nids;
13791 for (i = 0; i < cfg->line_outs; i++) {
13792 nid = cfg->line_out_pins[i];
13793 if (nid) {
13794 if (i >= ARRAY_SIZE(alc861_dac_nids))
13795 continue;
13796 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13797 }
13798 }
13799 spec->multiout.num_dacs = cfg->line_outs;
13800 return 0;
13801}
13802
13803/* add playback controls from the parsed DAC table */
13804static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13805 const struct auto_pin_cfg *cfg)
13806{
13807 char name[32];
f12ab1e0
TI
13808 static const char *chname[4] = {
13809 "Front", "Surround", NULL /*CLFE*/, "Side"
13810 };
df694daa
KY
13811 hda_nid_t nid;
13812 int i, idx, err;
13813
13814 for (i = 0; i < cfg->line_outs; i++) {
13815 nid = spec->multiout.dac_nids[i];
f12ab1e0 13816 if (!nid)
df694daa
KY
13817 continue;
13818 if (nid == 0x05) {
13819 /* Center/LFE */
f12ab1e0
TI
13820 err = add_control(spec, ALC_CTL_BIND_MUTE,
13821 "Center Playback Switch",
13822 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13823 HDA_OUTPUT));
13824 if (err < 0)
df694daa 13825 return err;
f12ab1e0
TI
13826 err = add_control(spec, ALC_CTL_BIND_MUTE,
13827 "LFE Playback Switch",
13828 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13829 HDA_OUTPUT));
13830 if (err < 0)
df694daa
KY
13831 return err;
13832 } else {
f12ab1e0
TI
13833 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13834 idx++)
df694daa
KY
13835 if (nid == alc861_dac_nids[idx])
13836 break;
13837 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
13838 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13839 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13840 HDA_OUTPUT));
13841 if (err < 0)
df694daa
KY
13842 return err;
13843 }
13844 }
13845 return 0;
13846}
13847
13848static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13849{
13850 int err;
13851 hda_nid_t nid;
13852
f12ab1e0 13853 if (!pin)
df694daa
KY
13854 return 0;
13855
13856 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13857 nid = 0x03;
f12ab1e0
TI
13858 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13859 "Headphone Playback Switch",
13860 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13861 if (err < 0)
df694daa
KY
13862 return err;
13863 spec->multiout.hp_nid = nid;
13864 }
13865 return 0;
13866}
13867
13868/* create playback/capture controls for input pins */
f12ab1e0
TI
13869static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13870 const struct auto_pin_cfg *cfg)
df694daa 13871{
61b9b9b1 13872 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
13873 int i, err, idx, idx1;
13874
13875 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 13876 switch (cfg->input_pins[i]) {
df694daa
KY
13877 case 0x0c:
13878 idx1 = 1;
f12ab1e0 13879 idx = 2; /* Line In */
df694daa
KY
13880 break;
13881 case 0x0f:
13882 idx1 = 2;
f12ab1e0 13883 idx = 2; /* Line In */
df694daa
KY
13884 break;
13885 case 0x0d:
13886 idx1 = 0;
f12ab1e0 13887 idx = 1; /* Mic In */
df694daa 13888 break;
f12ab1e0 13889 case 0x10:
df694daa 13890 idx1 = 3;
f12ab1e0 13891 idx = 1; /* Mic In */
df694daa
KY
13892 break;
13893 case 0x11:
13894 idx1 = 4;
f12ab1e0 13895 idx = 0; /* CD */
df694daa
KY
13896 break;
13897 default:
13898 continue;
13899 }
13900
4a471b7d
TI
13901 err = new_analog_input(spec, cfg->input_pins[i],
13902 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
13903 if (err < 0)
13904 return err;
13905
4a471b7d 13906 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 13907 imux->items[imux->num_items].index = idx1;
f12ab1e0 13908 imux->num_items++;
df694daa
KY
13909 }
13910 return 0;
13911}
13912
f12ab1e0
TI
13913static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13914 hda_nid_t nid,
df694daa
KY
13915 int pin_type, int dac_idx)
13916{
564c5bea
JL
13917 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13918 pin_type);
13919 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13920 AMP_OUT_UNMUTE);
df694daa
KY
13921}
13922
13923static void alc861_auto_init_multi_out(struct hda_codec *codec)
13924{
13925 struct alc_spec *spec = codec->spec;
13926 int i;
13927
bc9f98a9 13928 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
13929 for (i = 0; i < spec->autocfg.line_outs; i++) {
13930 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13931 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 13932 if (nid)
baba8ee9 13933 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 13934 spec->multiout.dac_nids[i]);
df694daa
KY
13935 }
13936}
13937
13938static void alc861_auto_init_hp_out(struct hda_codec *codec)
13939{
13940 struct alc_spec *spec = codec->spec;
13941 hda_nid_t pin;
13942
eb06ed8f 13943 pin = spec->autocfg.hp_pins[0];
df694daa 13944 if (pin) /* connect to front */
f12ab1e0
TI
13945 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13946 spec->multiout.dac_nids[0]);
f6c7e546
TI
13947 pin = spec->autocfg.speaker_pins[0];
13948 if (pin)
13949 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
13950}
13951
13952static void alc861_auto_init_analog_input(struct hda_codec *codec)
13953{
13954 struct alc_spec *spec = codec->spec;
13955 int i;
13956
13957 for (i = 0; i < AUTO_PIN_LAST; i++) {
13958 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
13959 if (nid >= 0x0c && nid <= 0x11)
13960 alc_set_input_pin(codec, nid, i);
df694daa
KY
13961 }
13962}
13963
13964/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
13965/* return 1 if successful, 0 if the proper config is not found,
13966 * or a negative error code
13967 */
df694daa
KY
13968static int alc861_parse_auto_config(struct hda_codec *codec)
13969{
13970 struct alc_spec *spec = codec->spec;
13971 int err;
13972 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13973
f12ab1e0
TI
13974 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13975 alc861_ignore);
13976 if (err < 0)
df694daa 13977 return err;
f12ab1e0 13978 if (!spec->autocfg.line_outs)
df694daa
KY
13979 return 0; /* can't find valid BIOS pin config */
13980
f12ab1e0
TI
13981 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13982 if (err < 0)
13983 return err;
13984 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13985 if (err < 0)
13986 return err;
13987 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13988 if (err < 0)
13989 return err;
13990 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13991 if (err < 0)
df694daa
KY
13992 return err;
13993
13994 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13995
0852d7a6 13996 if (spec->autocfg.dig_outs)
df694daa
KY
13997 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13998
603c4019 13999 if (spec->kctls.list)
d88897ea 14000 add_mixer(spec, spec->kctls.list);
df694daa 14001
d88897ea 14002 add_verb(spec, alc861_auto_init_verbs);
df694daa 14003
a1e8d2da 14004 spec->num_mux_defs = 1;
61b9b9b1 14005 spec->input_mux = &spec->private_imux[0];
df694daa
KY
14006
14007 spec->adc_nids = alc861_adc_nids;
14008 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
f9e336f6 14009 set_capture_mixer(spec);
df694daa
KY
14010
14011 return 1;
14012}
14013
ae6b813a
TI
14014/* additional initialization for auto-configuration model */
14015static void alc861_auto_init(struct hda_codec *codec)
df694daa 14016{
f6c7e546 14017 struct alc_spec *spec = codec->spec;
df694daa
KY
14018 alc861_auto_init_multi_out(codec);
14019 alc861_auto_init_hp_out(codec);
14020 alc861_auto_init_analog_input(codec);
f6c7e546 14021 if (spec->unsol_event)
7fb0d78f 14022 alc_inithook(codec);
df694daa
KY
14023}
14024
cb53c626
TI
14025#ifdef CONFIG_SND_HDA_POWER_SAVE
14026static struct hda_amp_list alc861_loopbacks[] = {
14027 { 0x15, HDA_INPUT, 0 },
14028 { 0x15, HDA_INPUT, 1 },
14029 { 0x15, HDA_INPUT, 2 },
14030 { 0x15, HDA_INPUT, 3 },
14031 { } /* end */
14032};
14033#endif
14034
df694daa
KY
14035
14036/*
14037 * configuration and preset
14038 */
f5fcc13c
TI
14039static const char *alc861_models[ALC861_MODEL_LAST] = {
14040 [ALC861_3ST] = "3stack",
14041 [ALC660_3ST] = "3stack-660",
14042 [ALC861_3ST_DIG] = "3stack-dig",
14043 [ALC861_6ST_DIG] = "6stack-dig",
14044 [ALC861_UNIWILL_M31] = "uniwill-m31",
14045 [ALC861_TOSHIBA] = "toshiba",
14046 [ALC861_ASUS] = "asus",
14047 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14048 [ALC861_AUTO] = "auto",
14049};
14050
14051static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 14052 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
14053 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14054 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14055 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 14056 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 14057 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 14058 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
14059 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14060 * Any other models that need this preset?
14061 */
14062 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
14063 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14064 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 14065 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
14066 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14067 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14068 /* FIXME: the below seems conflict */
14069 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 14070 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 14071 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
14072 {}
14073};
14074
14075static struct alc_config_preset alc861_presets[] = {
14076 [ALC861_3ST] = {
14077 .mixers = { alc861_3ST_mixer },
14078 .init_verbs = { alc861_threestack_init_verbs },
14079 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14080 .dac_nids = alc861_dac_nids,
14081 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14082 .channel_mode = alc861_threestack_modes,
4e195a7b 14083 .need_dac_fix = 1,
df694daa
KY
14084 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14085 .adc_nids = alc861_adc_nids,
14086 .input_mux = &alc861_capture_source,
14087 },
14088 [ALC861_3ST_DIG] = {
14089 .mixers = { alc861_base_mixer },
14090 .init_verbs = { alc861_threestack_init_verbs },
14091 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14092 .dac_nids = alc861_dac_nids,
14093 .dig_out_nid = ALC861_DIGOUT_NID,
14094 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14095 .channel_mode = alc861_threestack_modes,
4e195a7b 14096 .need_dac_fix = 1,
df694daa
KY
14097 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14098 .adc_nids = alc861_adc_nids,
14099 .input_mux = &alc861_capture_source,
14100 },
14101 [ALC861_6ST_DIG] = {
14102 .mixers = { alc861_base_mixer },
14103 .init_verbs = { alc861_base_init_verbs },
14104 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14105 .dac_nids = alc861_dac_nids,
14106 .dig_out_nid = ALC861_DIGOUT_NID,
14107 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14108 .channel_mode = alc861_8ch_modes,
14109 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14110 .adc_nids = alc861_adc_nids,
14111 .input_mux = &alc861_capture_source,
14112 },
9c7f852e
TI
14113 [ALC660_3ST] = {
14114 .mixers = { alc861_3ST_mixer },
14115 .init_verbs = { alc861_threestack_init_verbs },
14116 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14117 .dac_nids = alc660_dac_nids,
14118 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14119 .channel_mode = alc861_threestack_modes,
4e195a7b 14120 .need_dac_fix = 1,
9c7f852e
TI
14121 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14122 .adc_nids = alc861_adc_nids,
14123 .input_mux = &alc861_capture_source,
14124 },
22309c3e
TI
14125 [ALC861_UNIWILL_M31] = {
14126 .mixers = { alc861_uniwill_m31_mixer },
14127 .init_verbs = { alc861_uniwill_m31_init_verbs },
14128 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14129 .dac_nids = alc861_dac_nids,
14130 .dig_out_nid = ALC861_DIGOUT_NID,
14131 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14132 .channel_mode = alc861_uniwill_m31_modes,
14133 .need_dac_fix = 1,
14134 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14135 .adc_nids = alc861_adc_nids,
14136 .input_mux = &alc861_capture_source,
14137 },
a53d1aec
TD
14138 [ALC861_TOSHIBA] = {
14139 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
14140 .init_verbs = { alc861_base_init_verbs,
14141 alc861_toshiba_init_verbs },
a53d1aec
TD
14142 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14143 .dac_nids = alc861_dac_nids,
14144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14145 .channel_mode = alc883_3ST_2ch_modes,
14146 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14147 .adc_nids = alc861_adc_nids,
14148 .input_mux = &alc861_capture_source,
14149 .unsol_event = alc861_toshiba_unsol_event,
14150 .init_hook = alc861_toshiba_automute,
14151 },
7cdbff94
MD
14152 [ALC861_ASUS] = {
14153 .mixers = { alc861_asus_mixer },
14154 .init_verbs = { alc861_asus_init_verbs },
14155 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14156 .dac_nids = alc861_dac_nids,
14157 .dig_out_nid = ALC861_DIGOUT_NID,
14158 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14159 .channel_mode = alc861_asus_modes,
14160 .need_dac_fix = 1,
14161 .hp_nid = 0x06,
14162 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14163 .adc_nids = alc861_adc_nids,
14164 .input_mux = &alc861_capture_source,
14165 },
56bb0cab
TI
14166 [ALC861_ASUS_LAPTOP] = {
14167 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14168 .init_verbs = { alc861_asus_init_verbs,
14169 alc861_asus_laptop_init_verbs },
14170 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14171 .dac_nids = alc861_dac_nids,
14172 .dig_out_nid = ALC861_DIGOUT_NID,
14173 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14174 .channel_mode = alc883_3ST_2ch_modes,
14175 .need_dac_fix = 1,
14176 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14177 .adc_nids = alc861_adc_nids,
14178 .input_mux = &alc861_capture_source,
14179 },
14180};
df694daa
KY
14181
14182
14183static int patch_alc861(struct hda_codec *codec)
14184{
14185 struct alc_spec *spec;
14186 int board_config;
14187 int err;
14188
dc041e0b 14189 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
14190 if (spec == NULL)
14191 return -ENOMEM;
14192
f12ab1e0 14193 codec->spec = spec;
df694daa 14194
f5fcc13c
TI
14195 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14196 alc861_models,
14197 alc861_cfg_tbl);
9c7f852e 14198
f5fcc13c 14199 if (board_config < 0) {
9c7f852e
TI
14200 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14201 "trying auto-probe from BIOS...\n");
df694daa
KY
14202 board_config = ALC861_AUTO;
14203 }
14204
14205 if (board_config == ALC861_AUTO) {
14206 /* automatic parse from the BIOS config */
14207 err = alc861_parse_auto_config(codec);
14208 if (err < 0) {
14209 alc_free(codec);
14210 return err;
f12ab1e0 14211 } else if (!err) {
9c7f852e
TI
14212 printk(KERN_INFO
14213 "hda_codec: Cannot set up configuration "
14214 "from BIOS. Using base mode...\n");
df694daa
KY
14215 board_config = ALC861_3ST_DIG;
14216 }
14217 }
14218
680cd536
KK
14219 err = snd_hda_attach_beep_device(codec, 0x23);
14220 if (err < 0) {
14221 alc_free(codec);
14222 return err;
14223 }
14224
df694daa
KY
14225 if (board_config != ALC861_AUTO)
14226 setup_preset(spec, &alc861_presets[board_config]);
14227
14228 spec->stream_name_analog = "ALC861 Analog";
14229 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14230 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14231
14232 spec->stream_name_digital = "ALC861 Digital";
14233 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14234 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14235
45bdd1c1
TI
14236 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14237
2134ea4f
TI
14238 spec->vmaster_nid = 0x03;
14239
df694daa
KY
14240 codec->patch_ops = alc_patch_ops;
14241 if (board_config == ALC861_AUTO)
ae6b813a 14242 spec->init_hook = alc861_auto_init;
cb53c626
TI
14243#ifdef CONFIG_SND_HDA_POWER_SAVE
14244 if (!spec->loopback.amplist)
14245 spec->loopback.amplist = alc861_loopbacks;
14246#endif
daead538 14247 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 14248
1da177e4
LT
14249 return 0;
14250}
14251
f32610ed
JS
14252/*
14253 * ALC861-VD support
14254 *
14255 * Based on ALC882
14256 *
14257 * In addition, an independent DAC
14258 */
14259#define ALC861VD_DIGOUT_NID 0x06
14260
14261static hda_nid_t alc861vd_dac_nids[4] = {
14262 /* front, surr, clfe, side surr */
14263 0x02, 0x03, 0x04, 0x05
14264};
14265
14266/* dac_nids for ALC660vd are in a different order - according to
14267 * Realtek's driver.
14268 * This should probably tesult in a different mixer for 6stack models
14269 * of ALC660vd codecs, but for now there is only 3stack mixer
14270 * - and it is the same as in 861vd.
14271 * adc_nids in ALC660vd are (is) the same as in 861vd
14272 */
14273static hda_nid_t alc660vd_dac_nids[3] = {
14274 /* front, rear, clfe, rear_surr */
14275 0x02, 0x04, 0x03
14276};
14277
14278static hda_nid_t alc861vd_adc_nids[1] = {
14279 /* ADC0 */
14280 0x09,
14281};
14282
e1406348
TI
14283static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14284
f32610ed
JS
14285/* input MUX */
14286/* FIXME: should be a matrix-type input source selection */
14287static struct hda_input_mux alc861vd_capture_source = {
14288 .num_items = 4,
14289 .items = {
14290 { "Mic", 0x0 },
14291 { "Front Mic", 0x1 },
14292 { "Line", 0x2 },
14293 { "CD", 0x4 },
14294 },
14295};
14296
272a527c 14297static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 14298 .num_items = 2,
272a527c 14299 .items = {
b419f346
TD
14300 { "Ext Mic", 0x0 },
14301 { "Int Mic", 0x1 },
272a527c
KY
14302 },
14303};
14304
d1a991a6
KY
14305static struct hda_input_mux alc861vd_hp_capture_source = {
14306 .num_items = 2,
14307 .items = {
14308 { "Front Mic", 0x0 },
14309 { "ATAPI Mic", 0x1 },
14310 },
14311};
14312
f32610ed
JS
14313/*
14314 * 2ch mode
14315 */
14316static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14317 { 2, NULL }
14318};
14319
14320/*
14321 * 6ch mode
14322 */
14323static struct hda_verb alc861vd_6stack_ch6_init[] = {
14324 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14325 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14326 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14328 { } /* end */
14329};
14330
14331/*
14332 * 8ch mode
14333 */
14334static struct hda_verb alc861vd_6stack_ch8_init[] = {
14335 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14336 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14337 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14338 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14339 { } /* end */
14340};
14341
14342static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14343 { 6, alc861vd_6stack_ch6_init },
14344 { 8, alc861vd_6stack_ch8_init },
14345};
14346
14347static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14348 {
14349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14350 .name = "Channel Mode",
14351 .info = alc_ch_mode_info,
14352 .get = alc_ch_mode_get,
14353 .put = alc_ch_mode_put,
14354 },
14355 { } /* end */
14356};
14357
f32610ed
JS
14358/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14359 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14360 */
14361static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14362 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14364
14365 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14366 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14367
14368 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14369 HDA_OUTPUT),
14370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14371 HDA_OUTPUT),
14372 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14373 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14374
14375 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14376 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14377
14378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14379
14380 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14383
14384 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14387
14388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14390
14391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14393
f32610ed
JS
14394 { } /* end */
14395};
14396
14397static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14398 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14400
14401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14402
14403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14406
14407 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14408 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14409 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14410
14411 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14412 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14413
14414 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14415 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14416
f32610ed
JS
14417 { } /* end */
14418};
14419
bdd148a3
KY
14420static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14421 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14422 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14423 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14424
14425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14426
14427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14430
14431 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14434
14435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14437
14438 { } /* end */
14439};
14440
b419f346
TD
14441/* Pin assignment: Speaker=0x14, HP = 0x15,
14442 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
14443 */
14444static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
14445 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14446 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
14447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
14449 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14450 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14451 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14452 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14453 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14454 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
14455 { } /* end */
14456};
14457
d1a991a6
KY
14458/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14459 * Front Mic=0x18, ATAPI Mic = 0x19,
14460 */
14461static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14462 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14464 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14465 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14466 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14468 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14469 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 14470
d1a991a6
KY
14471 { } /* end */
14472};
14473
f32610ed
JS
14474/*
14475 * generic initialization of ADC, input mixers and output mixers
14476 */
14477static struct hda_verb alc861vd_volume_init_verbs[] = {
14478 /*
14479 * Unmute ADC0 and set the default input to mic-in
14480 */
14481 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14482 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14483
14484 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14485 * the analog-loopback mixer widget
14486 */
14487 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
14493
14494 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
14495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 14498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
14499
14500 /*
14501 * Set up output mixers (0x02 - 0x05)
14502 */
14503 /* set vol=0 to output mixers */
14504 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14508
14509 /* set up input amps for analog loopback */
14510 /* Amp Indices: DAC = 0, mixer = 1 */
14511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14517 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14519
14520 { }
14521};
14522
14523/*
14524 * 3-stack pin configuration:
14525 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14526 */
14527static struct hda_verb alc861vd_3stack_init_verbs[] = {
14528 /*
14529 * Set pin mode and muting
14530 */
14531 /* set front pin widgets 0x14 for output */
14532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14535
14536 /* Mic (rear) pin: input vref at 80% */
14537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14539 /* Front Mic pin: input vref at 80% */
14540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14542 /* Line In pin: input */
14543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14545 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14547 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14548 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14549 /* CD pin widget for input */
14550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14551
14552 { }
14553};
14554
14555/*
14556 * 6-stack pin configuration:
14557 */
14558static struct hda_verb alc861vd_6stack_init_verbs[] = {
14559 /*
14560 * Set pin mode and muting
14561 */
14562 /* set front pin widgets 0x14 for output */
14563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14565 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14566
14567 /* Rear Pin: output 1 (0x0d) */
14568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14570 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14571 /* CLFE Pin: output 2 (0x0e) */
14572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14573 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14574 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14575 /* Side Pin: output 3 (0x0f) */
14576 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14579
14580 /* Mic (rear) pin: input vref at 80% */
14581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14583 /* Front Mic pin: input vref at 80% */
14584 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14585 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14586 /* Line In pin: input */
14587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14589 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14592 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14593 /* CD pin widget for input */
14594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14595
14596 { }
14597};
14598
bdd148a3
KY
14599static struct hda_verb alc861vd_eapd_verbs[] = {
14600 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14601 { }
14602};
14603
f9423e7a
KY
14604static struct hda_verb alc660vd_eapd_verbs[] = {
14605 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14606 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14607 { }
14608};
14609
bdd148a3
KY
14610static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14613 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14614 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14615 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14616 {}
14617};
14618
14619/* toggle speaker-output according to the hp-jack state */
14620static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14621{
14622 unsigned int present;
14623 unsigned char bits;
14624
14625 present = snd_hda_codec_read(codec, 0x1b, 0,
14626 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14627 bits = present ? HDA_AMP_MUTE : 0;
14628 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14629 HDA_AMP_MUTE, bits);
bdd148a3
KY
14630}
14631
14632static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14633{
14634 unsigned int present;
14635 unsigned char bits;
14636
14637 present = snd_hda_codec_read(codec, 0x18, 0,
14638 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14639 bits = present ? HDA_AMP_MUTE : 0;
14640 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14641 HDA_AMP_MUTE, bits);
bdd148a3
KY
14642}
14643
14644static void alc861vd_lenovo_automute(struct hda_codec *codec)
14645{
14646 alc861vd_lenovo_hp_automute(codec);
14647 alc861vd_lenovo_mic_automute(codec);
14648}
14649
14650static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14651 unsigned int res)
14652{
14653 switch (res >> 26) {
14654 case ALC880_HP_EVENT:
14655 alc861vd_lenovo_hp_automute(codec);
14656 break;
14657 case ALC880_MIC_EVENT:
14658 alc861vd_lenovo_mic_automute(codec);
14659 break;
14660 }
14661}
14662
272a527c
KY
14663static struct hda_verb alc861vd_dallas_verbs[] = {
14664 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14665 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14666 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14667 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14668
14669 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14670 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14671 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14672 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14673 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14674 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14675 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14676 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14677
272a527c
KY
14678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14684 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14685 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14686
14687 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14688 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14689 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14690 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14691 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14693 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14694 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14695
14696 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14697 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14700
14701 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 14702 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
14703 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14704
14705 { } /* end */
14706};
14707
14708/* toggle speaker-output according to the hp-jack state */
14709static void alc861vd_dallas_automute(struct hda_codec *codec)
14710{
14711 unsigned int present;
14712
14713 present = snd_hda_codec_read(codec, 0x15, 0,
14714 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14715 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14716 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
14717}
14718
14719static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14720{
14721 if ((res >> 26) == ALC880_HP_EVENT)
14722 alc861vd_dallas_automute(codec);
14723}
14724
cb53c626
TI
14725#ifdef CONFIG_SND_HDA_POWER_SAVE
14726#define alc861vd_loopbacks alc880_loopbacks
14727#endif
14728
f32610ed
JS
14729/* pcm configuration: identiacal with ALC880 */
14730#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14731#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14732#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14733#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14734
14735/*
14736 * configuration and preset
14737 */
14738static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14739 [ALC660VD_3ST] = "3stack-660",
983f8ae4 14740 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 14741 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
14742 [ALC861VD_3ST] = "3stack",
14743 [ALC861VD_3ST_DIG] = "3stack-digout",
14744 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 14745 [ALC861VD_LENOVO] = "lenovo",
272a527c 14746 [ALC861VD_DALLAS] = "dallas",
983f8ae4 14747 [ALC861VD_HP] = "hp",
f32610ed
JS
14748 [ALC861VD_AUTO] = "auto",
14749};
14750
14751static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
14752 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14753 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 14754 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 14755 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13c94744 14756 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 14757 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 14758 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 14759 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 14760 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 14761 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 14762 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 14763 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 14764 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 14765 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 14766 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
14767 {}
14768};
14769
14770static struct alc_config_preset alc861vd_presets[] = {
14771 [ALC660VD_3ST] = {
14772 .mixers = { alc861vd_3st_mixer },
14773 .init_verbs = { alc861vd_volume_init_verbs,
14774 alc861vd_3stack_init_verbs },
14775 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14776 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14777 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14778 .channel_mode = alc861vd_3stack_2ch_modes,
14779 .input_mux = &alc861vd_capture_source,
14780 },
6963f84c
MC
14781 [ALC660VD_3ST_DIG] = {
14782 .mixers = { alc861vd_3st_mixer },
14783 .init_verbs = { alc861vd_volume_init_verbs,
14784 alc861vd_3stack_init_verbs },
14785 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14786 .dac_nids = alc660vd_dac_nids,
14787 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14788 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14789 .channel_mode = alc861vd_3stack_2ch_modes,
14790 .input_mux = &alc861vd_capture_source,
14791 },
f32610ed
JS
14792 [ALC861VD_3ST] = {
14793 .mixers = { alc861vd_3st_mixer },
14794 .init_verbs = { alc861vd_volume_init_verbs,
14795 alc861vd_3stack_init_verbs },
14796 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14797 .dac_nids = alc861vd_dac_nids,
14798 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14799 .channel_mode = alc861vd_3stack_2ch_modes,
14800 .input_mux = &alc861vd_capture_source,
14801 },
14802 [ALC861VD_3ST_DIG] = {
14803 .mixers = { alc861vd_3st_mixer },
14804 .init_verbs = { alc861vd_volume_init_verbs,
14805 alc861vd_3stack_init_verbs },
14806 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14807 .dac_nids = alc861vd_dac_nids,
14808 .dig_out_nid = ALC861VD_DIGOUT_NID,
14809 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14810 .channel_mode = alc861vd_3stack_2ch_modes,
14811 .input_mux = &alc861vd_capture_source,
14812 },
14813 [ALC861VD_6ST_DIG] = {
14814 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14815 .init_verbs = { alc861vd_volume_init_verbs,
14816 alc861vd_6stack_init_verbs },
14817 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14818 .dac_nids = alc861vd_dac_nids,
14819 .dig_out_nid = ALC861VD_DIGOUT_NID,
14820 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14821 .channel_mode = alc861vd_6stack_modes,
14822 .input_mux = &alc861vd_capture_source,
14823 },
bdd148a3
KY
14824 [ALC861VD_LENOVO] = {
14825 .mixers = { alc861vd_lenovo_mixer },
14826 .init_verbs = { alc861vd_volume_init_verbs,
14827 alc861vd_3stack_init_verbs,
14828 alc861vd_eapd_verbs,
14829 alc861vd_lenovo_unsol_verbs },
14830 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14831 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14832 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14833 .channel_mode = alc861vd_3stack_2ch_modes,
14834 .input_mux = &alc861vd_capture_source,
14835 .unsol_event = alc861vd_lenovo_unsol_event,
14836 .init_hook = alc861vd_lenovo_automute,
14837 },
272a527c
KY
14838 [ALC861VD_DALLAS] = {
14839 .mixers = { alc861vd_dallas_mixer },
14840 .init_verbs = { alc861vd_dallas_verbs },
14841 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14842 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14843 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14844 .channel_mode = alc861vd_3stack_2ch_modes,
14845 .input_mux = &alc861vd_dallas_capture_source,
14846 .unsol_event = alc861vd_dallas_unsol_event,
14847 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
14848 },
14849 [ALC861VD_HP] = {
14850 .mixers = { alc861vd_hp_mixer },
14851 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14852 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14853 .dac_nids = alc861vd_dac_nids,
d1a991a6 14854 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
14855 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14856 .channel_mode = alc861vd_3stack_2ch_modes,
14857 .input_mux = &alc861vd_hp_capture_source,
14858 .unsol_event = alc861vd_dallas_unsol_event,
14859 .init_hook = alc861vd_dallas_automute,
ea1fb29a 14860 },
13c94744
TI
14861 [ALC660VD_ASUS_V1S] = {
14862 .mixers = { alc861vd_lenovo_mixer },
14863 .init_verbs = { alc861vd_volume_init_verbs,
14864 alc861vd_3stack_init_verbs,
14865 alc861vd_eapd_verbs,
14866 alc861vd_lenovo_unsol_verbs },
14867 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14868 .dac_nids = alc660vd_dac_nids,
14869 .dig_out_nid = ALC861VD_DIGOUT_NID,
14870 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14871 .channel_mode = alc861vd_3stack_2ch_modes,
14872 .input_mux = &alc861vd_capture_source,
14873 .unsol_event = alc861vd_lenovo_unsol_event,
14874 .init_hook = alc861vd_lenovo_automute,
14875 },
f32610ed
JS
14876};
14877
14878/*
14879 * BIOS auto configuration
14880 */
14881static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14882 hda_nid_t nid, int pin_type, int dac_idx)
14883{
f6c7e546 14884 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
14885}
14886
14887static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14888{
14889 struct alc_spec *spec = codec->spec;
14890 int i;
14891
bc9f98a9 14892 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
14893 for (i = 0; i <= HDA_SIDE; i++) {
14894 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14895 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
14896 if (nid)
14897 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 14898 pin_type, i);
f32610ed
JS
14899 }
14900}
14901
14902
14903static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14904{
14905 struct alc_spec *spec = codec->spec;
14906 hda_nid_t pin;
14907
14908 pin = spec->autocfg.hp_pins[0];
14909 if (pin) /* connect to front and use dac 0 */
14910 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14911 pin = spec->autocfg.speaker_pins[0];
14912 if (pin)
14913 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
14914}
14915
14916#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14917#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14918
14919static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14920{
14921 struct alc_spec *spec = codec->spec;
14922 int i;
14923
14924 for (i = 0; i < AUTO_PIN_LAST; i++) {
14925 hda_nid_t nid = spec->autocfg.input_pins[i];
14926 if (alc861vd_is_input_pin(nid)) {
23f0c048 14927 alc_set_input_pin(codec, nid, i);
e82c025b
TI
14928 if (nid != ALC861VD_PIN_CD_NID &&
14929 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
14930 snd_hda_codec_write(codec, nid, 0,
14931 AC_VERB_SET_AMP_GAIN_MUTE,
14932 AMP_OUT_MUTE);
14933 }
14934 }
14935}
14936
f511b01c
TI
14937#define alc861vd_auto_init_input_src alc882_auto_init_input_src
14938
f32610ed
JS
14939#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14940#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14941
14942/* add playback controls from the parsed DAC table */
14943/* Based on ALC880 version. But ALC861VD has separate,
14944 * different NIDs for mute/unmute switch and volume control */
14945static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14946 const struct auto_pin_cfg *cfg)
14947{
14948 char name[32];
14949 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14950 hda_nid_t nid_v, nid_s;
14951 int i, err;
14952
14953 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 14954 if (!spec->multiout.dac_nids[i])
f32610ed
JS
14955 continue;
14956 nid_v = alc861vd_idx_to_mixer_vol(
14957 alc880_dac_to_idx(
14958 spec->multiout.dac_nids[i]));
14959 nid_s = alc861vd_idx_to_mixer_switch(
14960 alc880_dac_to_idx(
14961 spec->multiout.dac_nids[i]));
14962
14963 if (i == 2) {
14964 /* Center/LFE */
f12ab1e0
TI
14965 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14966 "Center Playback Volume",
14967 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14968 HDA_OUTPUT));
14969 if (err < 0)
f32610ed 14970 return err;
f12ab1e0
TI
14971 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14972 "LFE Playback Volume",
14973 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14974 HDA_OUTPUT));
14975 if (err < 0)
f32610ed 14976 return err;
f12ab1e0
TI
14977 err = add_control(spec, ALC_CTL_BIND_MUTE,
14978 "Center Playback Switch",
14979 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14980 HDA_INPUT));
14981 if (err < 0)
f32610ed 14982 return err;
f12ab1e0
TI
14983 err = add_control(spec, ALC_CTL_BIND_MUTE,
14984 "LFE Playback Switch",
14985 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14986 HDA_INPUT));
14987 if (err < 0)
f32610ed
JS
14988 return err;
14989 } else {
14990 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
14991 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14992 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14993 HDA_OUTPUT));
14994 if (err < 0)
f32610ed
JS
14995 return err;
14996 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 14997 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 14998 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
14999 HDA_INPUT));
15000 if (err < 0)
f32610ed
JS
15001 return err;
15002 }
15003 }
15004 return 0;
15005}
15006
15007/* add playback controls for speaker and HP outputs */
15008/* Based on ALC880 version. But ALC861VD has separate,
15009 * different NIDs for mute/unmute switch and volume control */
15010static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15011 hda_nid_t pin, const char *pfx)
15012{
15013 hda_nid_t nid_v, nid_s;
15014 int err;
15015 char name[32];
15016
f12ab1e0 15017 if (!pin)
f32610ed
JS
15018 return 0;
15019
15020 if (alc880_is_fixed_pin(pin)) {
15021 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15022 /* specify the DAC as the extra output */
f12ab1e0 15023 if (!spec->multiout.hp_nid)
f32610ed
JS
15024 spec->multiout.hp_nid = nid_v;
15025 else
15026 spec->multiout.extra_out_nid[0] = nid_v;
15027 /* control HP volume/switch on the output mixer amp */
15028 nid_v = alc861vd_idx_to_mixer_vol(
15029 alc880_fixed_pin_idx(pin));
15030 nid_s = alc861vd_idx_to_mixer_switch(
15031 alc880_fixed_pin_idx(pin));
15032
15033 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
15034 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15035 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15036 if (err < 0)
f32610ed
JS
15037 return err;
15038 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
15039 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15040 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15041 if (err < 0)
f32610ed
JS
15042 return err;
15043 } else if (alc880_is_multi_pin(pin)) {
15044 /* set manual connection */
15045 /* we have only a switch on HP-out PIN */
15046 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
15047 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15048 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15049 if (err < 0)
f32610ed
JS
15050 return err;
15051 }
15052 return 0;
15053}
15054
15055/* parse the BIOS configuration and set up the alc_spec
15056 * return 1 if successful, 0 if the proper config is not found,
15057 * or a negative error code
15058 * Based on ALC880 version - had to change it to override
15059 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15060static int alc861vd_parse_auto_config(struct hda_codec *codec)
15061{
15062 struct alc_spec *spec = codec->spec;
15063 int err;
15064 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15065
f12ab1e0
TI
15066 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15067 alc861vd_ignore);
15068 if (err < 0)
f32610ed 15069 return err;
f12ab1e0 15070 if (!spec->autocfg.line_outs)
f32610ed
JS
15071 return 0; /* can't find valid BIOS pin config */
15072
f12ab1e0
TI
15073 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15074 if (err < 0)
15075 return err;
15076 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15077 if (err < 0)
15078 return err;
15079 err = alc861vd_auto_create_extra_out(spec,
15080 spec->autocfg.speaker_pins[0],
15081 "Speaker");
15082 if (err < 0)
15083 return err;
15084 err = alc861vd_auto_create_extra_out(spec,
15085 spec->autocfg.hp_pins[0],
15086 "Headphone");
15087 if (err < 0)
15088 return err;
15089 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15090 if (err < 0)
f32610ed
JS
15091 return err;
15092
15093 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15094
0852d7a6 15095 if (spec->autocfg.dig_outs)
f32610ed
JS
15096 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15097
603c4019 15098 if (spec->kctls.list)
d88897ea 15099 add_mixer(spec, spec->kctls.list);
f32610ed 15100
d88897ea 15101 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
15102
15103 spec->num_mux_defs = 1;
61b9b9b1 15104 spec->input_mux = &spec->private_imux[0];
f32610ed 15105
776e184e
TI
15106 err = alc_auto_add_mic_boost(codec);
15107 if (err < 0)
15108 return err;
15109
f32610ed
JS
15110 return 1;
15111}
15112
15113/* additional initialization for auto-configuration model */
15114static void alc861vd_auto_init(struct hda_codec *codec)
15115{
f6c7e546 15116 struct alc_spec *spec = codec->spec;
f32610ed
JS
15117 alc861vd_auto_init_multi_out(codec);
15118 alc861vd_auto_init_hp_out(codec);
15119 alc861vd_auto_init_analog_input(codec);
f511b01c 15120 alc861vd_auto_init_input_src(codec);
f6c7e546 15121 if (spec->unsol_event)
7fb0d78f 15122 alc_inithook(codec);
f32610ed
JS
15123}
15124
15125static int patch_alc861vd(struct hda_codec *codec)
15126{
15127 struct alc_spec *spec;
15128 int err, board_config;
15129
15130 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15131 if (spec == NULL)
15132 return -ENOMEM;
15133
15134 codec->spec = spec;
15135
15136 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15137 alc861vd_models,
15138 alc861vd_cfg_tbl);
15139
15140 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15141 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
15142 "ALC861VD, trying auto-probe from BIOS...\n");
15143 board_config = ALC861VD_AUTO;
15144 }
15145
15146 if (board_config == ALC861VD_AUTO) {
15147 /* automatic parse from the BIOS config */
15148 err = alc861vd_parse_auto_config(codec);
15149 if (err < 0) {
15150 alc_free(codec);
15151 return err;
f12ab1e0 15152 } else if (!err) {
f32610ed
JS
15153 printk(KERN_INFO
15154 "hda_codec: Cannot set up configuration "
15155 "from BIOS. Using base mode...\n");
15156 board_config = ALC861VD_3ST;
15157 }
15158 }
15159
680cd536
KK
15160 err = snd_hda_attach_beep_device(codec, 0x23);
15161 if (err < 0) {
15162 alc_free(codec);
15163 return err;
15164 }
15165
f32610ed
JS
15166 if (board_config != ALC861VD_AUTO)
15167 setup_preset(spec, &alc861vd_presets[board_config]);
15168
2f893286
KY
15169 if (codec->vendor_id == 0x10ec0660) {
15170 spec->stream_name_analog = "ALC660-VD Analog";
15171 spec->stream_name_digital = "ALC660-VD Digital";
f9423e7a 15172 /* always turn on EAPD */
d88897ea 15173 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
15174 } else {
15175 spec->stream_name_analog = "ALC861VD Analog";
15176 spec->stream_name_digital = "ALC861VD Digital";
15177 }
15178
f32610ed
JS
15179 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15180 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15181
f32610ed
JS
15182 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15183 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15184
15185 spec->adc_nids = alc861vd_adc_nids;
15186 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 15187 spec->capsrc_nids = alc861vd_capsrc_nids;
61b9b9b1 15188 spec->capture_style = CAPT_MIX;
f32610ed 15189
f9e336f6 15190 set_capture_mixer(spec);
45bdd1c1 15191 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 15192
2134ea4f
TI
15193 spec->vmaster_nid = 0x02;
15194
f32610ed
JS
15195 codec->patch_ops = alc_patch_ops;
15196
15197 if (board_config == ALC861VD_AUTO)
15198 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
15199#ifdef CONFIG_SND_HDA_POWER_SAVE
15200 if (!spec->loopback.amplist)
15201 spec->loopback.amplist = alc861vd_loopbacks;
15202#endif
daead538 15203 codec->proc_widget_hook = print_realtek_coef;
f32610ed
JS
15204
15205 return 0;
15206}
15207
bc9f98a9
KY
15208/*
15209 * ALC662 support
15210 *
15211 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15212 * configuration. Each pin widget can choose any input DACs and a mixer.
15213 * Each ADC is connected from a mixer of all inputs. This makes possible
15214 * 6-channel independent captures.
15215 *
15216 * In addition, an independent DAC for the multi-playback (not used in this
15217 * driver yet).
15218 */
15219#define ALC662_DIGOUT_NID 0x06
15220#define ALC662_DIGIN_NID 0x0a
15221
15222static hda_nid_t alc662_dac_nids[4] = {
15223 /* front, rear, clfe, rear_surr */
15224 0x02, 0x03, 0x04
15225};
15226
622e84cd
KY
15227static hda_nid_t alc272_dac_nids[2] = {
15228 0x02, 0x03
15229};
15230
bc9f98a9
KY
15231static hda_nid_t alc662_adc_nids[1] = {
15232 /* ADC1-2 */
15233 0x09,
15234};
e1406348 15235
622e84cd
KY
15236static hda_nid_t alc272_adc_nids[1] = {
15237 /* ADC1-2 */
15238 0x08,
15239};
15240
77a261b7 15241static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
622e84cd
KY
15242static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15243
e1406348 15244
bc9f98a9
KY
15245/* input MUX */
15246/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
15247static struct hda_input_mux alc662_capture_source = {
15248 .num_items = 4,
15249 .items = {
15250 { "Mic", 0x0 },
15251 { "Front Mic", 0x1 },
15252 { "Line", 0x2 },
15253 { "CD", 0x4 },
15254 },
15255};
15256
15257static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15258 .num_items = 2,
15259 .items = {
15260 { "Mic", 0x1 },
15261 { "Line", 0x2 },
15262 },
15263};
291702f0
KY
15264
15265static struct hda_input_mux alc662_eeepc_capture_source = {
15266 .num_items = 2,
15267 .items = {
15268 { "i-Mic", 0x1 },
15269 { "e-Mic", 0x0 },
15270 },
15271};
15272
6dda9f4a
KY
15273static struct hda_input_mux alc663_capture_source = {
15274 .num_items = 3,
15275 .items = {
15276 { "Mic", 0x0 },
15277 { "Front Mic", 0x1 },
15278 { "Line", 0x2 },
15279 },
15280};
15281
15282static struct hda_input_mux alc663_m51va_capture_source = {
15283 .num_items = 2,
15284 .items = {
15285 { "Ext-Mic", 0x0 },
15286 { "D-Mic", 0x9 },
15287 },
15288};
15289
bc9f98a9
KY
15290/*
15291 * 2ch mode
15292 */
15293static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15294 { 2, NULL }
15295};
15296
15297/*
15298 * 2ch mode
15299 */
15300static struct hda_verb alc662_3ST_ch2_init[] = {
15301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15305 { } /* end */
15306};
15307
15308/*
15309 * 6ch mode
15310 */
15311static struct hda_verb alc662_3ST_ch6_init[] = {
15312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15314 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15317 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15318 { } /* end */
15319};
15320
15321static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15322 { 2, alc662_3ST_ch2_init },
15323 { 6, alc662_3ST_ch6_init },
15324};
15325
15326/*
15327 * 2ch mode
15328 */
15329static struct hda_verb alc662_sixstack_ch6_init[] = {
15330 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15331 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15332 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15333 { } /* end */
15334};
15335
15336/*
15337 * 6ch mode
15338 */
15339static struct hda_verb alc662_sixstack_ch8_init[] = {
15340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15343 { } /* end */
15344};
15345
15346static struct hda_channel_mode alc662_5stack_modes[2] = {
15347 { 2, alc662_sixstack_ch6_init },
15348 { 6, alc662_sixstack_ch8_init },
15349};
15350
15351/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15352 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15353 */
15354
15355static struct snd_kcontrol_new alc662_base_mixer[] = {
15356 /* output mixer control */
15357 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 15358 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15359 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 15360 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15361 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15362 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15363 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15364 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15366
15367 /*Input mixer control */
15368 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15369 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15370 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15371 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15372 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15373 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15374 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
15376 { } /* end */
15377};
15378
15379static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15380 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15381 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
15382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15389 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15391 { } /* end */
15392};
15393
15394static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15396 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15397 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 15398 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15399 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15401 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15402 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15404 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15405 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15406 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15407 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15408 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15409 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15410 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15412 { } /* end */
15413};
15414
15415static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15416 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15417 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
15418 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15419 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
15420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15425 { } /* end */
15426};
15427
291702f0 15428static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 15429 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 15430
b4818494
HRK
15431 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
15433
15434 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15435 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15436 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15437
15438 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15439 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15440 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15441 { } /* end */
15442};
15443
8c427226 15444static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
15445 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
15447 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15448 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15449 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15451 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15452 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 15453 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
15454 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15459 { } /* end */
15460};
15461
f1d4e28b
KY
15462static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15463 .ops = &snd_hda_bind_vol,
15464 .values = {
15465 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15466 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15467 0
15468 },
15469};
15470
15471static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15472 .ops = &snd_hda_bind_sw,
15473 .values = {
15474 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15475 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15476 0
15477 },
15478};
15479
6dda9f4a 15480static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
15481 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15482 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15485 { } /* end */
15486};
15487
15488static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15489 .ops = &snd_hda_bind_sw,
15490 .values = {
15491 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15492 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15493 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15494 0
15495 },
15496};
15497
15498static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15499 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15500 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15502 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15503 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15504 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15505
15506 { } /* end */
15507};
15508
15509static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15510 .ops = &snd_hda_bind_sw,
15511 .values = {
15512 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15513 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15514 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15515 0
15516 },
15517};
15518
15519static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15520 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15521 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15524 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15525 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15526 { } /* end */
15527};
15528
15529static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
15530 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15531 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
15532 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15535 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15536 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15537 { } /* end */
15538};
15539
15540static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15541 .ops = &snd_hda_bind_vol,
15542 .values = {
15543 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15544 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15545 0
15546 },
15547};
15548
15549static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15550 .ops = &snd_hda_bind_sw,
15551 .values = {
15552 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15553 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15554 0
15555 },
15556};
15557
15558static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15559 HDA_BIND_VOL("Master Playback Volume",
15560 &alc663_asus_two_bind_master_vol),
15561 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15562 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
15563 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
15566 { } /* end */
15567};
15568
15569static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15570 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15571 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15572 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
15576 { } /* end */
15577};
15578
15579static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15582 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15583 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15585
15586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15588 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15589 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15590 { } /* end */
15591};
15592
15593static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15594 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15595 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15597
15598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15600 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15601 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15602 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15603 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15604 { } /* end */
15605};
15606
bc9f98a9
KY
15607static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15608 {
15609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15610 .name = "Channel Mode",
15611 .info = alc_ch_mode_info,
15612 .get = alc_ch_mode_get,
15613 .put = alc_ch_mode_put,
15614 },
15615 { } /* end */
15616};
15617
15618static struct hda_verb alc662_init_verbs[] = {
15619 /* ADC: mute amp left and right */
15620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15622 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15623
cb53c626
TI
15624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15629
b60dd394
KY
15630 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15631 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15632 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15635 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15636
15637 /* Front Pin: output 0 (0x0c) */
15638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15640
15641 /* Rear Pin: output 1 (0x0d) */
15642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15644
15645 /* CLFE Pin: output 2 (0x0e) */
15646 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15648
15649 /* Mic (rear) pin: input vref at 80% */
15650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15652 /* Front Mic pin: input vref at 80% */
15653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15655 /* Line In pin: input */
15656 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15658 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15661 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15662 /* CD pin widget for input */
15663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15664
15665 /* FIXME: use matrix-type input source selection */
15666 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15667 /* Input mixer */
15668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 15669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
15670
15671 /* always trun on EAPD */
15672 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15673 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15674
bc9f98a9
KY
15675 { }
15676};
15677
15678static struct hda_verb alc662_sue_init_verbs[] = {
15679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15680 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
15681 {}
15682};
15683
15684static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15685 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15687 {}
bc9f98a9
KY
15688};
15689
8c427226
KY
15690/* Set Unsolicited Event*/
15691static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15694 {}
15695};
15696
bc9f98a9
KY
15697/*
15698 * generic initialization of ADC, input mixers and output mixers
15699 */
15700static struct hda_verb alc662_auto_init_verbs[] = {
15701 /*
15702 * Unmute ADC and set the default input to mic-in
15703 */
15704 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706
15707 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15708 * mixer widget
15709 * Note: PASD motherboards uses the Line In 2 as the input for front
15710 * panel mic (mic 2)
15711 */
15712 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
15718
15719 /*
15720 * Set up output mixers (0x0c - 0x0f)
15721 */
15722 /* set vol=0 to output mixers */
15723 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15724 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15725 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15726
15727 /* set up input amps for analog loopback */
15728 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
15729 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15732 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15735
15736
15737 /* FIXME: use matrix-type input source selection */
15738 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15739 /* Input mixer */
15740 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 15741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
15742 { }
15743};
15744
24fb9173
TI
15745/* additional verbs for ALC663 */
15746static struct hda_verb alc663_auto_init_verbs[] = {
15747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15749 { }
15750};
15751
6dda9f4a 15752static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
15753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15754 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
15755 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15756 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
15757 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15760 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15761 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15762 {}
15763};
15764
15765static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15766 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15767 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15768 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15772 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15773 {}
15774};
15775
15776static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15779 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15780 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15784 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15785 {}
15786};
6dda9f4a 15787
f1d4e28b
KY
15788static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15790 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15791 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15796 {}
15797};
6dda9f4a 15798
f1d4e28b
KY
15799static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15800 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15801 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15802 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15803 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15804 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15807 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15809 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15810 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15811 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15812 {}
15813};
15814
15815static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15816 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15825 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15826 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15827 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
15828 {}
15829};
15830
15831static struct hda_verb alc663_g71v_init_verbs[] = {
15832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15833 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15834 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15835
15836 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15837 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15838 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15839
15840 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15841 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15842 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15843 {}
15844};
15845
15846static struct hda_verb alc663_g50v_init_verbs[] = {
15847 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15848 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15849 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15850
15851 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15852 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15853 {}
15854};
15855
f1d4e28b
KY
15856static struct hda_verb alc662_ecs_init_verbs[] = {
15857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15860 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15861 {}
15862};
15863
622e84cd
KY
15864static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15865 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15866 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15869 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15870 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15871 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15874 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15875 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15876 {}
15877};
15878
15879static struct hda_verb alc272_dell_init_verbs[] = {
15880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15881 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15883 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15884 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15885 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15886 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15890 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15891 {}
15892};
15893
f1d4e28b
KY
15894static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15895 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15896 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15897 { } /* end */
15898};
15899
622e84cd
KY
15900static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15901 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15902 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15903 { } /* end */
15904};
15905
bc9f98a9
KY
15906static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15907{
15908 unsigned int present;
f12ab1e0 15909 unsigned char bits;
bc9f98a9
KY
15910
15911 present = snd_hda_codec_read(codec, 0x14, 0,
15912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15913 bits = present ? HDA_AMP_MUTE : 0;
15914 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15915 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15916}
15917
15918static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15919{
15920 unsigned int present;
f12ab1e0 15921 unsigned char bits;
bc9f98a9
KY
15922
15923 present = snd_hda_codec_read(codec, 0x1b, 0,
15924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15925 bits = present ? HDA_AMP_MUTE : 0;
15926 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15927 HDA_AMP_MUTE, bits);
15928 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15929 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15930}
15931
15932static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15933 unsigned int res)
15934{
15935 if ((res >> 26) == ALC880_HP_EVENT)
15936 alc662_lenovo_101e_all_automute(codec);
15937 if ((res >> 26) == ALC880_FRONT_EVENT)
15938 alc662_lenovo_101e_ispeaker_automute(codec);
15939}
15940
291702f0
KY
15941static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15942{
15943 unsigned int present;
15944
15945 present = snd_hda_codec_read(codec, 0x18, 0,
15946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15947 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15948 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15949 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15950 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15951 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15952 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15953 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15954 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15955}
15956
15957/* unsolicited event for HP jack sensing */
15958static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15959 unsigned int res)
15960{
15961 if ((res >> 26) == ALC880_HP_EVENT)
15962 alc262_hippo1_automute( codec );
15963
15964 if ((res >> 26) == ALC880_MIC_EVENT)
15965 alc662_eeepc_mic_automute(codec);
15966}
15967
15968static void alc662_eeepc_inithook(struct hda_codec *codec)
15969{
15970 alc262_hippo1_automute( codec );
15971 alc662_eeepc_mic_automute(codec);
15972}
15973
8c427226
KY
15974static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15975{
15976 unsigned int mute;
15977 unsigned int present;
15978
15979 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15980 present = snd_hda_codec_read(codec, 0x14, 0,
15981 AC_VERB_GET_PIN_SENSE, 0);
15982 present = (present & 0x80000000) != 0;
15983 if (present) {
15984 /* mute internal speaker */
15985 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15986 HDA_AMP_MUTE, HDA_AMP_MUTE);
8c427226
KY
15987 } else {
15988 /* unmute internal speaker if necessary */
15989 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15990 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15991 HDA_AMP_MUTE, mute);
8c427226
KY
15992 }
15993}
15994
15995/* unsolicited event for HP jack sensing */
15996static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15997 unsigned int res)
15998{
15999 if ((res >> 26) == ALC880_HP_EVENT)
16000 alc662_eeepc_ep20_automute(codec);
16001}
16002
16003static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16004{
16005 alc662_eeepc_ep20_automute(codec);
16006}
16007
6dda9f4a
KY
16008static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16009{
16010 unsigned int present;
16011 unsigned char bits;
16012
16013 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
16014 AC_VERB_GET_PIN_SENSE, 0)
16015 & AC_PINSENSE_PRESENCE;
6dda9f4a 16016 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
16017 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16018 AMP_IN_MUTE(0), bits);
16019 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16020 AMP_IN_MUTE(0), bits);
16021}
16022
16023static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16024{
16025 unsigned int present;
16026 unsigned char bits;
16027
16028 present = snd_hda_codec_read(codec, 0x21, 0,
16029 AC_VERB_GET_PIN_SENSE, 0)
16030 & AC_PINSENSE_PRESENCE;
16031 bits = present ? HDA_AMP_MUTE : 0;
16032 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16033 AMP_IN_MUTE(0), bits);
16034 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16035 AMP_IN_MUTE(0), bits);
16036 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16037 AMP_IN_MUTE(0), bits);
16038 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16039 AMP_IN_MUTE(0), bits);
16040}
16041
16042static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16043{
16044 unsigned int present;
16045 unsigned char bits;
16046
16047 present = snd_hda_codec_read(codec, 0x15, 0,
16048 AC_VERB_GET_PIN_SENSE, 0)
16049 & AC_PINSENSE_PRESENCE;
16050 bits = present ? HDA_AMP_MUTE : 0;
16051 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16052 AMP_IN_MUTE(0), bits);
16053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16054 AMP_IN_MUTE(0), bits);
16055 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16056 AMP_IN_MUTE(0), bits);
16057 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16058 AMP_IN_MUTE(0), bits);
16059}
16060
16061static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16062{
16063 unsigned int present;
16064 unsigned char bits;
16065
16066 present = snd_hda_codec_read(codec, 0x1b, 0,
16067 AC_VERB_GET_PIN_SENSE, 0)
16068 & AC_PINSENSE_PRESENCE;
16069 bits = present ? 0 : PIN_OUT;
16070 snd_hda_codec_write(codec, 0x14, 0,
16071 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16072}
16073
16074static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16075{
16076 unsigned int present1, present2;
16077
16078 present1 = snd_hda_codec_read(codec, 0x21, 0,
16079 AC_VERB_GET_PIN_SENSE, 0)
16080 & AC_PINSENSE_PRESENCE;
16081 present2 = snd_hda_codec_read(codec, 0x15, 0,
16082 AC_VERB_GET_PIN_SENSE, 0)
16083 & AC_PINSENSE_PRESENCE;
16084
16085 if (present1 || present2) {
16086 snd_hda_codec_write_cache(codec, 0x14, 0,
16087 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16088 } else {
16089 snd_hda_codec_write_cache(codec, 0x14, 0,
16090 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16091 }
16092}
16093
16094static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16095{
16096 unsigned int present1, present2;
16097
16098 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16099 AC_VERB_GET_PIN_SENSE, 0)
16100 & AC_PINSENSE_PRESENCE;
16101 present2 = snd_hda_codec_read(codec, 0x15, 0,
16102 AC_VERB_GET_PIN_SENSE, 0)
16103 & AC_PINSENSE_PRESENCE;
16104
16105 if (present1 || present2) {
16106 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16107 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16108 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16109 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16110 } else {
16111 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16112 AMP_IN_MUTE(0), 0);
16113 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16114 AMP_IN_MUTE(0), 0);
16115 }
6dda9f4a
KY
16116}
16117
16118static void alc663_m51va_mic_automute(struct hda_codec *codec)
16119{
16120 unsigned int present;
16121
16122 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
16123 AC_VERB_GET_PIN_SENSE, 0)
16124 & AC_PINSENSE_PRESENCE;
6dda9f4a 16125 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16126 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 16127 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16128 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 16129 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16130 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 16131 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16132 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
16133}
16134
16135static void alc663_m51va_unsol_event(struct hda_codec *codec,
16136 unsigned int res)
16137{
16138 switch (res >> 26) {
16139 case ALC880_HP_EVENT:
16140 alc663_m51va_speaker_automute(codec);
16141 break;
16142 case ALC880_MIC_EVENT:
16143 alc663_m51va_mic_automute(codec);
16144 break;
16145 }
16146}
16147
16148static void alc663_m51va_inithook(struct hda_codec *codec)
16149{
16150 alc663_m51va_speaker_automute(codec);
16151 alc663_m51va_mic_automute(codec);
16152}
16153
f1d4e28b
KY
16154/* ***************** Mode1 ******************************/
16155static void alc663_mode1_unsol_event(struct hda_codec *codec,
16156 unsigned int res)
16157{
16158 switch (res >> 26) {
16159 case ALC880_HP_EVENT:
16160 alc663_m51va_speaker_automute(codec);
16161 break;
16162 case ALC880_MIC_EVENT:
16163 alc662_eeepc_mic_automute(codec);
16164 break;
16165 }
16166}
16167
16168static void alc663_mode1_inithook(struct hda_codec *codec)
16169{
16170 alc663_m51va_speaker_automute(codec);
16171 alc662_eeepc_mic_automute(codec);
16172}
16173/* ***************** Mode2 ******************************/
16174static void alc662_mode2_unsol_event(struct hda_codec *codec,
16175 unsigned int res)
16176{
16177 switch (res >> 26) {
16178 case ALC880_HP_EVENT:
16179 alc662_f5z_speaker_automute(codec);
16180 break;
16181 case ALC880_MIC_EVENT:
16182 alc662_eeepc_mic_automute(codec);
16183 break;
16184 }
16185}
16186
16187static void alc662_mode2_inithook(struct hda_codec *codec)
16188{
16189 alc662_f5z_speaker_automute(codec);
16190 alc662_eeepc_mic_automute(codec);
16191}
16192/* ***************** Mode3 ******************************/
16193static void alc663_mode3_unsol_event(struct hda_codec *codec,
16194 unsigned int res)
16195{
16196 switch (res >> 26) {
16197 case ALC880_HP_EVENT:
16198 alc663_two_hp_m1_speaker_automute(codec);
16199 break;
16200 case ALC880_MIC_EVENT:
16201 alc662_eeepc_mic_automute(codec);
16202 break;
16203 }
16204}
16205
16206static void alc663_mode3_inithook(struct hda_codec *codec)
16207{
16208 alc663_two_hp_m1_speaker_automute(codec);
16209 alc662_eeepc_mic_automute(codec);
16210}
16211/* ***************** Mode4 ******************************/
16212static void alc663_mode4_unsol_event(struct hda_codec *codec,
16213 unsigned int res)
16214{
16215 switch (res >> 26) {
16216 case ALC880_HP_EVENT:
16217 alc663_21jd_two_speaker_automute(codec);
16218 break;
16219 case ALC880_MIC_EVENT:
16220 alc662_eeepc_mic_automute(codec);
16221 break;
16222 }
16223}
16224
16225static void alc663_mode4_inithook(struct hda_codec *codec)
16226{
16227 alc663_21jd_two_speaker_automute(codec);
16228 alc662_eeepc_mic_automute(codec);
16229}
16230/* ***************** Mode5 ******************************/
16231static void alc663_mode5_unsol_event(struct hda_codec *codec,
16232 unsigned int res)
16233{
16234 switch (res >> 26) {
16235 case ALC880_HP_EVENT:
16236 alc663_15jd_two_speaker_automute(codec);
16237 break;
16238 case ALC880_MIC_EVENT:
16239 alc662_eeepc_mic_automute(codec);
16240 break;
16241 }
16242}
16243
16244static void alc663_mode5_inithook(struct hda_codec *codec)
16245{
16246 alc663_15jd_two_speaker_automute(codec);
16247 alc662_eeepc_mic_automute(codec);
16248}
16249/* ***************** Mode6 ******************************/
16250static void alc663_mode6_unsol_event(struct hda_codec *codec,
16251 unsigned int res)
16252{
16253 switch (res >> 26) {
16254 case ALC880_HP_EVENT:
16255 alc663_two_hp_m2_speaker_automute(codec);
16256 break;
16257 case ALC880_MIC_EVENT:
16258 alc662_eeepc_mic_automute(codec);
16259 break;
16260 }
16261}
16262
16263static void alc663_mode6_inithook(struct hda_codec *codec)
16264{
16265 alc663_two_hp_m2_speaker_automute(codec);
16266 alc662_eeepc_mic_automute(codec);
16267}
16268
6dda9f4a
KY
16269static void alc663_g71v_hp_automute(struct hda_codec *codec)
16270{
16271 unsigned int present;
16272 unsigned char bits;
16273
16274 present = snd_hda_codec_read(codec, 0x21, 0,
16275 AC_VERB_GET_PIN_SENSE, 0)
16276 & AC_PINSENSE_PRESENCE;
16277 bits = present ? HDA_AMP_MUTE : 0;
16278 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16279 HDA_AMP_MUTE, bits);
16280 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16281 HDA_AMP_MUTE, bits);
16282}
16283
16284static void alc663_g71v_front_automute(struct hda_codec *codec)
16285{
16286 unsigned int present;
16287 unsigned char bits;
16288
16289 present = snd_hda_codec_read(codec, 0x15, 0,
16290 AC_VERB_GET_PIN_SENSE, 0)
16291 & AC_PINSENSE_PRESENCE;
16292 bits = present ? HDA_AMP_MUTE : 0;
16293 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16294 HDA_AMP_MUTE, bits);
16295}
16296
16297static void alc663_g71v_unsol_event(struct hda_codec *codec,
16298 unsigned int res)
16299{
16300 switch (res >> 26) {
16301 case ALC880_HP_EVENT:
16302 alc663_g71v_hp_automute(codec);
16303 break;
16304 case ALC880_FRONT_EVENT:
16305 alc663_g71v_front_automute(codec);
16306 break;
16307 case ALC880_MIC_EVENT:
16308 alc662_eeepc_mic_automute(codec);
16309 break;
16310 }
16311}
16312
16313static void alc663_g71v_inithook(struct hda_codec *codec)
16314{
16315 alc663_g71v_front_automute(codec);
16316 alc663_g71v_hp_automute(codec);
16317 alc662_eeepc_mic_automute(codec);
16318}
16319
16320static void alc663_g50v_unsol_event(struct hda_codec *codec,
16321 unsigned int res)
16322{
16323 switch (res >> 26) {
16324 case ALC880_HP_EVENT:
16325 alc663_m51va_speaker_automute(codec);
16326 break;
16327 case ALC880_MIC_EVENT:
16328 alc662_eeepc_mic_automute(codec);
16329 break;
16330 }
16331}
16332
16333static void alc663_g50v_inithook(struct hda_codec *codec)
16334{
16335 alc663_m51va_speaker_automute(codec);
16336 alc662_eeepc_mic_automute(codec);
16337}
16338
f1d4e28b
KY
16339/* bind hp and internal speaker mute (with plug check) */
16340static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16341 struct snd_ctl_elem_value *ucontrol)
16342{
16343 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16344 long *valp = ucontrol->value.integer.value;
16345 int change;
16346
16347 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16348 HDA_AMP_MUTE,
16349 valp[0] ? 0 : HDA_AMP_MUTE);
16350 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16351 HDA_AMP_MUTE,
16352 valp[1] ? 0 : HDA_AMP_MUTE);
16353 if (change)
16354 alc262_hippo1_automute(codec);
16355 return change;
16356}
16357
16358static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16359 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16360 {
16361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16362 .name = "Master Playback Switch",
16363 .info = snd_hda_mixer_amp_switch_info,
16364 .get = snd_hda_mixer_amp_switch_get,
16365 .put = alc662_ecs_master_sw_put,
16366 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16367 },
16368
16369 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16370 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16371 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16372
16373 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16374 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16375 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16376 { } /* end */
16377};
16378
cb53c626
TI
16379#ifdef CONFIG_SND_HDA_POWER_SAVE
16380#define alc662_loopbacks alc880_loopbacks
16381#endif
16382
bc9f98a9
KY
16383
16384/* pcm configuration: identiacal with ALC880 */
16385#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16386#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16387#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16388#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16389
16390/*
16391 * configuration and preset
16392 */
16393static const char *alc662_models[ALC662_MODEL_LAST] = {
16394 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16395 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16396 [ALC662_3ST_6ch] = "3stack-6ch",
16397 [ALC662_5ST_DIG] = "6stack-dig",
16398 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 16399 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 16400 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 16401 [ALC662_ECS] = "ecs",
6dda9f4a
KY
16402 [ALC663_ASUS_M51VA] = "m51va",
16403 [ALC663_ASUS_G71V] = "g71v",
16404 [ALC663_ASUS_H13] = "h13",
16405 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
16406 [ALC663_ASUS_MODE1] = "asus-mode1",
16407 [ALC662_ASUS_MODE2] = "asus-mode2",
16408 [ALC663_ASUS_MODE3] = "asus-mode3",
16409 [ALC663_ASUS_MODE4] = "asus-mode4",
16410 [ALC663_ASUS_MODE5] = "asus-mode5",
16411 [ALC663_ASUS_MODE6] = "asus-mode6",
bc9f98a9
KY
16412 [ALC662_AUTO] = "auto",
16413};
16414
16415static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 16416 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
16417 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16418 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 16419 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509
TI
16420 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16421 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 16422 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 16423 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 16424 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16425 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16426 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16427 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16428 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16429 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16430 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd
KY
16431 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16432 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16433 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 16434 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16435 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16436 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16437 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 16438 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 16439 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16440 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16441 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16442 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 16443 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 16444 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd
KY
16445 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16446 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16447 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
16448 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16449 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16450 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 16451 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
16452 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16453 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 16454 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
16455 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16456 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16457 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16458 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16459 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 16460 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 16461 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16462 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
16463 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16464 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16465 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16466 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
16467 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16468 ALC662_3ST_6ch_DIG),
cb55974c
HRK
16469 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16470 ALC662_3ST_6ch_DIG),
19c009aa 16471 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 16472 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 16473 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 16474 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 16475 ALC662_3ST_6ch_DIG),
dea0a509
TI
16476 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16477 ALC663_ASUS_H13),
bc9f98a9
KY
16478 {}
16479};
16480
16481static struct alc_config_preset alc662_presets[] = {
16482 [ALC662_3ST_2ch_DIG] = {
f9e336f6 16483 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
16484 .init_verbs = { alc662_init_verbs },
16485 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16486 .dac_nids = alc662_dac_nids,
16487 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16488 .dig_in_nid = ALC662_DIGIN_NID,
16489 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16490 .channel_mode = alc662_3ST_2ch_modes,
16491 .input_mux = &alc662_capture_source,
16492 },
16493 [ALC662_3ST_6ch_DIG] = {
f9e336f6 16494 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16495 .init_verbs = { alc662_init_verbs },
16496 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16497 .dac_nids = alc662_dac_nids,
16498 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16499 .dig_in_nid = ALC662_DIGIN_NID,
16500 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16501 .channel_mode = alc662_3ST_6ch_modes,
16502 .need_dac_fix = 1,
16503 .input_mux = &alc662_capture_source,
f12ab1e0 16504 },
bc9f98a9 16505 [ALC662_3ST_6ch] = {
f9e336f6 16506 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16507 .init_verbs = { alc662_init_verbs },
16508 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16509 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16510 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16511 .channel_mode = alc662_3ST_6ch_modes,
16512 .need_dac_fix = 1,
16513 .input_mux = &alc662_capture_source,
f12ab1e0 16514 },
bc9f98a9 16515 [ALC662_5ST_DIG] = {
f9e336f6 16516 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16517 .init_verbs = { alc662_init_verbs },
16518 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16519 .dac_nids = alc662_dac_nids,
16520 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16521 .dig_in_nid = ALC662_DIGIN_NID,
16522 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16523 .channel_mode = alc662_5stack_modes,
16524 .input_mux = &alc662_capture_source,
16525 },
16526 [ALC662_LENOVO_101E] = {
f9e336f6 16527 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
16528 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16529 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16530 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16531 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16532 .channel_mode = alc662_3ST_2ch_modes,
16533 .input_mux = &alc662_lenovo_101e_capture_source,
16534 .unsol_event = alc662_lenovo_101e_unsol_event,
16535 .init_hook = alc662_lenovo_101e_all_automute,
16536 },
291702f0 16537 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 16538 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
16539 .init_verbs = { alc662_init_verbs,
16540 alc662_eeepc_sue_init_verbs },
16541 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16542 .dac_nids = alc662_dac_nids,
291702f0
KY
16543 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16544 .channel_mode = alc662_3ST_2ch_modes,
16545 .input_mux = &alc662_eeepc_capture_source,
16546 .unsol_event = alc662_eeepc_unsol_event,
16547 .init_hook = alc662_eeepc_inithook,
16548 },
8c427226 16549 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 16550 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
16551 alc662_chmode_mixer },
16552 .init_verbs = { alc662_init_verbs,
16553 alc662_eeepc_ep20_sue_init_verbs },
16554 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16555 .dac_nids = alc662_dac_nids,
8c427226
KY
16556 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16557 .channel_mode = alc662_3ST_6ch_modes,
16558 .input_mux = &alc662_lenovo_101e_capture_source,
16559 .unsol_event = alc662_eeepc_ep20_unsol_event,
16560 .init_hook = alc662_eeepc_ep20_inithook,
16561 },
f1d4e28b 16562 [ALC662_ECS] = {
f9e336f6 16563 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
16564 .init_verbs = { alc662_init_verbs,
16565 alc662_ecs_init_verbs },
16566 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16567 .dac_nids = alc662_dac_nids,
16568 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16569 .channel_mode = alc662_3ST_2ch_modes,
16570 .input_mux = &alc662_eeepc_capture_source,
16571 .unsol_event = alc662_eeepc_unsol_event,
16572 .init_hook = alc662_eeepc_inithook,
16573 },
6dda9f4a 16574 [ALC663_ASUS_M51VA] = {
f9e336f6 16575 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16576 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16577 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16578 .dac_nids = alc662_dac_nids,
16579 .dig_out_nid = ALC662_DIGOUT_NID,
16580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16581 .channel_mode = alc662_3ST_2ch_modes,
16582 .input_mux = &alc663_m51va_capture_source,
16583 .unsol_event = alc663_m51va_unsol_event,
16584 .init_hook = alc663_m51va_inithook,
16585 },
16586 [ALC663_ASUS_G71V] = {
f9e336f6 16587 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
16588 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16589 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16590 .dac_nids = alc662_dac_nids,
16591 .dig_out_nid = ALC662_DIGOUT_NID,
16592 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16593 .channel_mode = alc662_3ST_2ch_modes,
16594 .input_mux = &alc662_eeepc_capture_source,
16595 .unsol_event = alc663_g71v_unsol_event,
16596 .init_hook = alc663_g71v_inithook,
16597 },
16598 [ALC663_ASUS_H13] = {
f9e336f6 16599 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16600 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16602 .dac_nids = alc662_dac_nids,
16603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16604 .channel_mode = alc662_3ST_2ch_modes,
16605 .input_mux = &alc663_m51va_capture_source,
16606 .unsol_event = alc663_m51va_unsol_event,
16607 .init_hook = alc663_m51va_inithook,
16608 },
16609 [ALC663_ASUS_G50V] = {
f9e336f6 16610 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
16611 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16612 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16613 .dac_nids = alc662_dac_nids,
16614 .dig_out_nid = ALC662_DIGOUT_NID,
16615 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16616 .channel_mode = alc662_3ST_6ch_modes,
16617 .input_mux = &alc663_capture_source,
16618 .unsol_event = alc663_g50v_unsol_event,
16619 .init_hook = alc663_g50v_inithook,
16620 },
f1d4e28b 16621 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
16622 .mixers = { alc663_m51va_mixer },
16623 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16624 .init_verbs = { alc662_init_verbs,
16625 alc663_21jd_amic_init_verbs },
16626 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16627 .hp_nid = 0x03,
16628 .dac_nids = alc662_dac_nids,
16629 .dig_out_nid = ALC662_DIGOUT_NID,
16630 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16631 .channel_mode = alc662_3ST_2ch_modes,
16632 .input_mux = &alc662_eeepc_capture_source,
16633 .unsol_event = alc663_mode1_unsol_event,
16634 .init_hook = alc663_mode1_inithook,
16635 },
16636 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
16637 .mixers = { alc662_1bjd_mixer },
16638 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16639 .init_verbs = { alc662_init_verbs,
16640 alc662_1bjd_amic_init_verbs },
16641 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16642 .dac_nids = alc662_dac_nids,
16643 .dig_out_nid = ALC662_DIGOUT_NID,
16644 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16645 .channel_mode = alc662_3ST_2ch_modes,
16646 .input_mux = &alc662_eeepc_capture_source,
16647 .unsol_event = alc662_mode2_unsol_event,
16648 .init_hook = alc662_mode2_inithook,
16649 },
16650 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
16651 .mixers = { alc663_two_hp_m1_mixer },
16652 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16653 .init_verbs = { alc662_init_verbs,
16654 alc663_two_hp_amic_m1_init_verbs },
16655 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16656 .hp_nid = 0x03,
16657 .dac_nids = alc662_dac_nids,
16658 .dig_out_nid = ALC662_DIGOUT_NID,
16659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16660 .channel_mode = alc662_3ST_2ch_modes,
16661 .input_mux = &alc662_eeepc_capture_source,
16662 .unsol_event = alc663_mode3_unsol_event,
16663 .init_hook = alc663_mode3_inithook,
16664 },
16665 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
16666 .mixers = { alc663_asus_21jd_clfe_mixer },
16667 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16668 .init_verbs = { alc662_init_verbs,
16669 alc663_21jd_amic_init_verbs},
16670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16671 .hp_nid = 0x03,
16672 .dac_nids = alc662_dac_nids,
16673 .dig_out_nid = ALC662_DIGOUT_NID,
16674 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16675 .channel_mode = alc662_3ST_2ch_modes,
16676 .input_mux = &alc662_eeepc_capture_source,
16677 .unsol_event = alc663_mode4_unsol_event,
16678 .init_hook = alc663_mode4_inithook,
16679 },
16680 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
16681 .mixers = { alc663_asus_15jd_clfe_mixer },
16682 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16683 .init_verbs = { alc662_init_verbs,
16684 alc663_15jd_amic_init_verbs },
16685 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16686 .hp_nid = 0x03,
16687 .dac_nids = alc662_dac_nids,
16688 .dig_out_nid = ALC662_DIGOUT_NID,
16689 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16690 .channel_mode = alc662_3ST_2ch_modes,
16691 .input_mux = &alc662_eeepc_capture_source,
16692 .unsol_event = alc663_mode5_unsol_event,
16693 .init_hook = alc663_mode5_inithook,
16694 },
16695 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
16696 .mixers = { alc663_two_hp_m2_mixer },
16697 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16698 .init_verbs = { alc662_init_verbs,
16699 alc663_two_hp_amic_m2_init_verbs },
16700 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16701 .hp_nid = 0x03,
16702 .dac_nids = alc662_dac_nids,
16703 .dig_out_nid = ALC662_DIGOUT_NID,
16704 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16705 .channel_mode = alc662_3ST_2ch_modes,
16706 .input_mux = &alc662_eeepc_capture_source,
16707 .unsol_event = alc663_mode6_unsol_event,
16708 .init_hook = alc663_mode6_inithook,
16709 },
622e84cd
KY
16710 [ALC272_DELL] = {
16711 .mixers = { alc663_m51va_mixer },
16712 .cap_mixer = alc272_auto_capture_mixer,
16713 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16714 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16715 .dac_nids = alc662_dac_nids,
16716 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16717 .adc_nids = alc272_adc_nids,
16718 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16719 .capsrc_nids = alc272_capsrc_nids,
16720 .channel_mode = alc662_3ST_2ch_modes,
16721 .input_mux = &alc663_m51va_capture_source,
16722 .unsol_event = alc663_m51va_unsol_event,
16723 .init_hook = alc663_m51va_inithook,
16724 },
16725 [ALC272_DELL_ZM1] = {
16726 .mixers = { alc663_m51va_mixer },
16727 .cap_mixer = alc662_auto_capture_mixer,
16728 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16729 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16730 .dac_nids = alc662_dac_nids,
16731 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16732 .adc_nids = alc662_adc_nids,
16733 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16734 .capsrc_nids = alc662_capsrc_nids,
16735 .channel_mode = alc662_3ST_2ch_modes,
16736 .input_mux = &alc663_m51va_capture_source,
16737 .unsol_event = alc663_m51va_unsol_event,
16738 .init_hook = alc663_m51va_inithook,
16739 },
bc9f98a9
KY
16740};
16741
16742
16743/*
16744 * BIOS auto configuration
16745 */
16746
16747/* add playback controls from the parsed DAC table */
16748static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16749 const struct auto_pin_cfg *cfg)
16750{
16751 char name[32];
16752 static const char *chname[4] = {
16753 "Front", "Surround", NULL /*CLFE*/, "Side"
16754 };
16755 hda_nid_t nid;
16756 int i, err;
16757
16758 for (i = 0; i < cfg->line_outs; i++) {
16759 if (!spec->multiout.dac_nids[i])
16760 continue;
b60dd394 16761 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
16762 if (i == 2) {
16763 /* Center/LFE */
16764 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16765 "Center Playback Volume",
f12ab1e0
TI
16766 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16767 HDA_OUTPUT));
bc9f98a9
KY
16768 if (err < 0)
16769 return err;
16770 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16771 "LFE Playback Volume",
f12ab1e0
TI
16772 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16773 HDA_OUTPUT));
bc9f98a9
KY
16774 if (err < 0)
16775 return err;
b69ce01a 16776 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16777 "Center Playback Switch",
b69ce01a 16778 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 16779 HDA_INPUT));
bc9f98a9
KY
16780 if (err < 0)
16781 return err;
b69ce01a 16782 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16783 "LFE Playback Switch",
b69ce01a 16784 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 16785 HDA_INPUT));
bc9f98a9
KY
16786 if (err < 0)
16787 return err;
16788 } else {
16789 sprintf(name, "%s Playback Volume", chname[i]);
16790 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
16791 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16792 HDA_OUTPUT));
bc9f98a9
KY
16793 if (err < 0)
16794 return err;
16795 sprintf(name, "%s Playback Switch", chname[i]);
b69ce01a
HRK
16796 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16797 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16798 3, 0, HDA_INPUT));
bc9f98a9
KY
16799 if (err < 0)
16800 return err;
16801 }
16802 }
16803 return 0;
16804}
16805
16806/* add playback controls for speaker and HP outputs */
16807static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16808 const char *pfx)
16809{
16810 hda_nid_t nid;
16811 int err;
16812 char name[32];
16813
16814 if (!pin)
16815 return 0;
16816
24fb9173
TI
16817 if (pin == 0x17) {
16818 /* ALC663 has a mono output pin on 0x17 */
16819 sprintf(name, "%s Playback Switch", pfx);
16820 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16821 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16822 return err;
16823 }
16824
bc9f98a9
KY
16825 if (alc880_is_fixed_pin(pin)) {
16826 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
939778ae 16827 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
bc9f98a9
KY
16828 /* specify the DAC as the extra output */
16829 if (!spec->multiout.hp_nid)
16830 spec->multiout.hp_nid = nid;
16831 else
16832 spec->multiout.extra_out_nid[0] = nid;
16833 /* control HP volume/switch on the output mixer amp */
16834 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16835 sprintf(name, "%s Playback Volume", pfx);
16836 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16837 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16838 if (err < 0)
16839 return err;
16840 sprintf(name, "%s Playback Switch", pfx);
16841 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16842 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16843 if (err < 0)
16844 return err;
16845 } else if (alc880_is_multi_pin(pin)) {
16846 /* set manual connection */
16847 /* we have only a switch on HP-out PIN */
16848 sprintf(name, "%s Playback Switch", pfx);
16849 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16850 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16851 if (err < 0)
16852 return err;
16853 }
16854 return 0;
16855}
16856
2d864c49
TI
16857/* return the index of the src widget from the connection list of the nid.
16858 * return -1 if not found
16859 */
16860static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16861 hda_nid_t src)
16862{
16863 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16864 int i, conns;
16865
16866 conns = snd_hda_get_connections(codec, nid, conn_list,
16867 ARRAY_SIZE(conn_list));
16868 if (conns < 0)
16869 return -1;
16870 for (i = 0; i < conns; i++)
16871 if (conn_list[i] == src)
16872 return i;
16873 return -1;
16874}
16875
16876static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16877{
1327a32b 16878 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2d864c49
TI
16879 return (pincap & AC_PINCAP_IN) != 0;
16880}
16881
bc9f98a9 16882/* create playback/capture controls for input pins */
2d864c49 16883static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
bc9f98a9
KY
16884 const struct auto_pin_cfg *cfg)
16885{
2d864c49 16886 struct alc_spec *spec = codec->spec;
61b9b9b1 16887 struct hda_input_mux *imux = &spec->private_imux[0];
bc9f98a9
KY
16888 int i, err, idx;
16889
16890 for (i = 0; i < AUTO_PIN_LAST; i++) {
2d864c49
TI
16891 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16892 idx = alc662_input_pin_idx(codec, 0x0b,
16893 cfg->input_pins[i]);
16894 if (idx >= 0) {
16895 err = new_analog_input(spec, cfg->input_pins[i],
16896 auto_pin_cfg_labels[i],
16897 idx, 0x0b);
16898 if (err < 0)
16899 return err;
16900 }
16901 idx = alc662_input_pin_idx(codec, 0x22,
16902 cfg->input_pins[i]);
16903 if (idx >= 0) {
16904 imux->items[imux->num_items].label =
16905 auto_pin_cfg_labels[i];
16906 imux->items[imux->num_items].index = idx;
16907 imux->num_items++;
16908 }
bc9f98a9
KY
16909 }
16910 }
16911 return 0;
16912}
16913
16914static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16915 hda_nid_t nid, int pin_type,
16916 int dac_idx)
16917{
f6c7e546 16918 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
16919 /* need the manual connection? */
16920 if (alc880_is_multi_pin(nid)) {
16921 struct alc_spec *spec = codec->spec;
16922 int idx = alc880_multi_pin_idx(nid);
16923 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16924 AC_VERB_SET_CONNECT_SEL,
16925 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16926 }
16927}
16928
16929static void alc662_auto_init_multi_out(struct hda_codec *codec)
16930{
16931 struct alc_spec *spec = codec->spec;
16932 int i;
16933
8c427226 16934 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
16935 for (i = 0; i <= HDA_SIDE; i++) {
16936 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16937 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 16938 if (nid)
baba8ee9 16939 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
16940 i);
16941 }
16942}
16943
16944static void alc662_auto_init_hp_out(struct hda_codec *codec)
16945{
16946 struct alc_spec *spec = codec->spec;
16947 hda_nid_t pin;
16948
16949 pin = spec->autocfg.hp_pins[0];
16950 if (pin) /* connect to front */
16951 /* use dac 0 */
16952 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16953 pin = spec->autocfg.speaker_pins[0];
16954 if (pin)
16955 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
16956}
16957
bc9f98a9
KY
16958#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16959
16960static void alc662_auto_init_analog_input(struct hda_codec *codec)
16961{
16962 struct alc_spec *spec = codec->spec;
16963 int i;
16964
16965 for (i = 0; i < AUTO_PIN_LAST; i++) {
16966 hda_nid_t nid = spec->autocfg.input_pins[i];
2d864c49 16967 if (alc662_is_input_pin(codec, nid)) {
23f0c048 16968 alc_set_input_pin(codec, nid, i);
52ca15b7 16969 if (nid != ALC662_PIN_CD_NID &&
e82c025b 16970 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
16971 snd_hda_codec_write(codec, nid, 0,
16972 AC_VERB_SET_AMP_GAIN_MUTE,
16973 AMP_OUT_MUTE);
16974 }
16975 }
16976}
16977
f511b01c
TI
16978#define alc662_auto_init_input_src alc882_auto_init_input_src
16979
bc9f98a9
KY
16980static int alc662_parse_auto_config(struct hda_codec *codec)
16981{
16982 struct alc_spec *spec = codec->spec;
16983 int err;
16984 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16985
16986 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16987 alc662_ignore);
16988 if (err < 0)
16989 return err;
16990 if (!spec->autocfg.line_outs)
16991 return 0; /* can't find valid BIOS pin config */
16992
f12ab1e0
TI
16993 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16994 if (err < 0)
16995 return err;
16996 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16997 if (err < 0)
16998 return err;
16999 err = alc662_auto_create_extra_out(spec,
17000 spec->autocfg.speaker_pins[0],
17001 "Speaker");
17002 if (err < 0)
17003 return err;
17004 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17005 "Headphone");
17006 if (err < 0)
17007 return err;
2d864c49 17008 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
f12ab1e0 17009 if (err < 0)
bc9f98a9
KY
17010 return err;
17011
17012 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17013
0852d7a6 17014 if (spec->autocfg.dig_outs)
bc9f98a9
KY
17015 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17016
603c4019 17017 if (spec->kctls.list)
d88897ea 17018 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
17019
17020 spec->num_mux_defs = 1;
61b9b9b1 17021 spec->input_mux = &spec->private_imux[0];
ea1fb29a 17022
d88897ea 17023 add_verb(spec, alc662_auto_init_verbs);
24fb9173 17024 if (codec->vendor_id == 0x10ec0663)
d88897ea 17025 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
17026
17027 err = alc_auto_add_mic_boost(codec);
17028 if (err < 0)
17029 return err;
17030
8c87286f 17031 return 1;
bc9f98a9
KY
17032}
17033
17034/* additional initialization for auto-configuration model */
17035static void alc662_auto_init(struct hda_codec *codec)
17036{
f6c7e546 17037 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
17038 alc662_auto_init_multi_out(codec);
17039 alc662_auto_init_hp_out(codec);
17040 alc662_auto_init_analog_input(codec);
f511b01c 17041 alc662_auto_init_input_src(codec);
f6c7e546 17042 if (spec->unsol_event)
7fb0d78f 17043 alc_inithook(codec);
bc9f98a9
KY
17044}
17045
17046static int patch_alc662(struct hda_codec *codec)
17047{
17048 struct alc_spec *spec;
17049 int err, board_config;
17050
17051 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17052 if (!spec)
17053 return -ENOMEM;
17054
17055 codec->spec = spec;
17056
2c3bf9ab
TI
17057 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17058
bc9f98a9
KY
17059 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17060 alc662_models,
17061 alc662_cfg_tbl);
17062 if (board_config < 0) {
17063 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
17064 "trying auto-probe from BIOS...\n");
17065 board_config = ALC662_AUTO;
17066 }
17067
17068 if (board_config == ALC662_AUTO) {
17069 /* automatic parse from the BIOS config */
17070 err = alc662_parse_auto_config(codec);
17071 if (err < 0) {
17072 alc_free(codec);
17073 return err;
8c87286f 17074 } else if (!err) {
bc9f98a9
KY
17075 printk(KERN_INFO
17076 "hda_codec: Cannot set up configuration "
17077 "from BIOS. Using base mode...\n");
17078 board_config = ALC662_3ST_2ch_DIG;
17079 }
17080 }
17081
680cd536
KK
17082 err = snd_hda_attach_beep_device(codec, 0x1);
17083 if (err < 0) {
17084 alc_free(codec);
17085 return err;
17086 }
17087
bc9f98a9
KY
17088 if (board_config != ALC662_AUTO)
17089 setup_preset(spec, &alc662_presets[board_config]);
17090
6dda9f4a
KY
17091 if (codec->vendor_id == 0x10ec0663) {
17092 spec->stream_name_analog = "ALC663 Analog";
17093 spec->stream_name_digital = "ALC663 Digital";
01afd41f
KY
17094 } else if (codec->vendor_id == 0x10ec0272) {
17095 spec->stream_name_analog = "ALC272 Analog";
17096 spec->stream_name_digital = "ALC272 Digital";
6dda9f4a
KY
17097 } else {
17098 spec->stream_name_analog = "ALC662 Analog";
17099 spec->stream_name_digital = "ALC662 Digital";
17100 }
17101
bc9f98a9
KY
17102 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17103 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17104
bc9f98a9
KY
17105 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17106 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17107
e1406348
TI
17108 spec->adc_nids = alc662_adc_nids;
17109 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17110 spec->capsrc_nids = alc662_capsrc_nids;
61b9b9b1 17111 spec->capture_style = CAPT_MIX;
bc9f98a9 17112
f9e336f6
TI
17113 if (!spec->cap_mixer)
17114 set_capture_mixer(spec);
b9591448
TI
17115 if (codec->vendor_id == 0x10ec0662)
17116 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17117 else
17118 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f9e336f6 17119
2134ea4f
TI
17120 spec->vmaster_nid = 0x02;
17121
bc9f98a9
KY
17122 codec->patch_ops = alc_patch_ops;
17123 if (board_config == ALC662_AUTO)
17124 spec->init_hook = alc662_auto_init;
cb53c626
TI
17125#ifdef CONFIG_SND_HDA_POWER_SAVE
17126 if (!spec->loopback.amplist)
17127 spec->loopback.amplist = alc662_loopbacks;
17128#endif
daead538 17129 codec->proc_widget_hook = print_realtek_coef;
bc9f98a9
KY
17130
17131 return 0;
17132}
17133
1da177e4
LT
17134/*
17135 * patch entries
17136 */
1289e9e8 17137static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 17138 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 17139 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 17140 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 17141 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 17142 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 17143 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 17144 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 17145 .patch = patch_alc861 },
f32610ed
JS
17146 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17147 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17148 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
17149 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17150 .patch = patch_alc883 },
17151 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17152 .patch = patch_alc662 },
6dda9f4a 17153 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 17154 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 17155 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 17156 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
669faba2
CM
17157 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17158 .patch = patch_alc882 }, /* should be patch_alc883() in future */
cb308f97 17159 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 17160 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 17161 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
a385a529 17162 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
4442608d
KY
17163 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17164 .patch = patch_alc883 },
3fea2cb0 17165 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 17166 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
17167 {} /* terminator */
17168};
1289e9e8
TI
17169
17170MODULE_ALIAS("snd-hda-codec-id:10ec*");
17171
17172MODULE_LICENSE("GPL");
17173MODULE_DESCRIPTION("Realtek HD-audio codec");
17174
17175static struct hda_codec_preset_list realtek_list = {
17176 .preset = snd_hda_preset_realtek,
17177 .owner = THIS_MODULE,
17178};
17179
17180static int __init patch_realtek_init(void)
17181{
17182 return snd_hda_add_codec_preset(&realtek_list);
17183}
17184
17185static void __exit patch_realtek_exit(void)
17186{
17187 snd_hda_delete_codec_preset(&realtek_list);
17188}
17189
17190module_init(patch_realtek_init)
17191module_exit(patch_realtek_exit)