]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda_intel: fix build error when !PM
[net-next-2.6.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
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,
9541ba1d 193 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
194 ALC662_AUTO,
195 ALC662_MODEL_LAST,
196};
197
df694daa
KY
198/* ALC882 models */
199enum {
200 ALC882_3ST_DIG,
201 ALC882_6ST_DIG,
4b146cb0 202 ALC882_ARIMA,
bdd148a3 203 ALC882_W2JC,
272a527c
KY
204 ALC882_TARGA,
205 ALC882_ASUS_A7J,
914759b7 206 ALC882_ASUS_A7M,
9102cd1c 207 ALC885_MACPRO,
87350ad0 208 ALC885_MBP3,
41d5545d 209 ALC885_MB5,
c54728d8 210 ALC885_IMAC24,
272a527c 211 ALC882_AUTO,
df694daa
KY
212 ALC882_MODEL_LAST,
213};
214
9c7f852e
TI
215/* ALC883 models */
216enum {
217 ALC883_3ST_2ch_DIG,
218 ALC883_3ST_6ch_DIG,
219 ALC883_3ST_6ch,
220 ALC883_6ST_DIG,
ccc656ce
KY
221 ALC883_TARGA_DIG,
222 ALC883_TARGA_2ch_DIG,
bab282b9 223 ALC883_ACER,
2880a867 224 ALC883_ACER_ASPIRE,
5b2d1eca 225 ALC888_ACER_ASPIRE_4930G,
3b315d70 226 ALC888_ACER_ASPIRE_8930G,
c07584c8 227 ALC883_MEDION,
ea1fb29a 228 ALC883_MEDION_MD2,
b373bdeb 229 ALC883_LAPTOP_EAPD,
bc9f98a9 230 ALC883_LENOVO_101E_2ch,
272a527c 231 ALC883_LENOVO_NB0763,
189609ae 232 ALC888_LENOVO_MS7195_DIG,
e2757d5e 233 ALC888_LENOVO_SKY,
ea1fb29a 234 ALC883_HAIER_W66,
4723c022 235 ALC888_3ST_HP,
5795b9e6 236 ALC888_6ST_DELL,
a8848bd6 237 ALC883_MITAC,
0c4cc443 238 ALC883_CLEVO_M720,
fb97dc67 239 ALC883_FUJITSU_PI2515,
ef8ef5fb 240 ALC888_FUJITSU_XA3530,
17bba1b7 241 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
242 ALC888_ASUS_M90V,
243 ALC888_ASUS_EEE1601,
eb4c41d3 244 ALC889A_MB31,
3ab90935 245 ALC1200_ASUS_P5Q,
9c7f852e
TI
246 ALC883_AUTO,
247 ALC883_MODEL_LAST,
248};
249
61b9b9b1
HRK
250/* styles of capture selection */
251enum {
252 CAPT_MUX = 0, /* only mux based */
253 CAPT_MIX, /* only mixer based */
254 CAPT_1MUX_MIX, /* first mux and other mixers */
255};
256
df694daa
KY
257/* for GPIO Poll */
258#define GPIO_MASK 0x03
259
4a79ba34
TI
260/* extra amp-initialization sequence types */
261enum {
262 ALC_INIT_NONE,
263 ALC_INIT_DEFAULT,
264 ALC_INIT_GPIO1,
265 ALC_INIT_GPIO2,
266 ALC_INIT_GPIO3,
267};
268
1da177e4
LT
269struct alc_spec {
270 /* codec parameterization */
df694daa 271 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 272 unsigned int num_mixers;
f9e336f6 273 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 274 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 275
df694daa 276 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
277 * don't forget NULL
278 * termination!
e9edcee0
TI
279 */
280 unsigned int num_init_verbs;
1da177e4 281
812a2cca 282 char stream_name_analog[16]; /* analog PCM stream */
1da177e4
LT
283 struct hda_pcm_stream *stream_analog_playback;
284 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
285 struct hda_pcm_stream *stream_analog_alt_playback;
286 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 287
812a2cca 288 char stream_name_digital[16]; /* digital PCM stream */
1da177e4
LT
289 struct hda_pcm_stream *stream_digital_playback;
290 struct hda_pcm_stream *stream_digital_capture;
291
292 /* playback */
16ded525
TI
293 struct hda_multi_out multiout; /* playback set-up
294 * max_channels, dacs must be set
295 * dig_out_nid and hp_nid are optional
296 */
6330079f 297 hda_nid_t alt_dac_nid;
6a05ac4a 298 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 299 int dig_out_type;
1da177e4
LT
300
301 /* capture */
302 unsigned int num_adc_nids;
303 hda_nid_t *adc_nids;
e1406348 304 hda_nid_t *capsrc_nids;
16ded525 305 hda_nid_t dig_in_nid; /* digital-in NID; optional */
61b9b9b1 306 int capture_style; /* capture style (CAPT_*) */
1da177e4
LT
307
308 /* capture source */
a1e8d2da 309 unsigned int num_mux_defs;
1da177e4
LT
310 const struct hda_input_mux *input_mux;
311 unsigned int cur_mux[3];
312
313 /* channel model */
d2a6d7dc 314 const struct hda_channel_mode *channel_mode;
1da177e4 315 int num_channel_mode;
4e195a7b 316 int need_dac_fix;
3b315d70
HM
317 int const_channel_count;
318 int ext_channel_count;
1da177e4
LT
319
320 /* PCM information */
4c5186ed 321 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 322
e9edcee0
TI
323 /* dynamic controls, init_verbs and input_mux */
324 struct auto_pin_cfg autocfg;
603c4019 325 struct snd_array kctls;
61b9b9b1 326 struct hda_input_mux private_imux[3];
41923e44 327 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 328
ae6b813a
TI
329 /* hooks */
330 void (*init_hook)(struct hda_codec *codec);
331 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
332
834be88d
TI
333 /* for pin sensing */
334 unsigned int sense_updated: 1;
335 unsigned int jack_present: 1;
bec15c3a 336 unsigned int master_sw: 1;
cb53c626 337
e64f14f4
TI
338 /* other flags */
339 unsigned int no_analog :1; /* digital I/O only */
4a79ba34 340 int init_amp;
e64f14f4 341
2134ea4f
TI
342 /* for virtual master */
343 hda_nid_t vmaster_nid;
cb53c626
TI
344#ifdef CONFIG_SND_HDA_POWER_SAVE
345 struct hda_loopback_check loopback;
346#endif
2c3bf9ab
TI
347
348 /* for PLL fix */
349 hda_nid_t pll_nid;
350 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
351};
352
353/*
354 * configuration template - to be copied to the spec instance
355 */
356struct alc_config_preset {
9c7f852e
TI
357 struct snd_kcontrol_new *mixers[5]; /* should be identical size
358 * with spec
359 */
f9e336f6 360 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
361 const struct hda_verb *init_verbs[5];
362 unsigned int num_dacs;
363 hda_nid_t *dac_nids;
364 hda_nid_t dig_out_nid; /* optional */
365 hda_nid_t hp_nid; /* optional */
b25c9da1 366 hda_nid_t *slave_dig_outs;
df694daa
KY
367 unsigned int num_adc_nids;
368 hda_nid_t *adc_nids;
e1406348 369 hda_nid_t *capsrc_nids;
df694daa
KY
370 hda_nid_t dig_in_nid;
371 unsigned int num_channel_mode;
372 const struct hda_channel_mode *channel_mode;
4e195a7b 373 int need_dac_fix;
3b315d70 374 int const_channel_count;
a1e8d2da 375 unsigned int num_mux_defs;
df694daa 376 const struct hda_input_mux *input_mux;
ae6b813a
TI
377 void (*unsol_event)(struct hda_codec *, unsigned int);
378 void (*init_hook)(struct hda_codec *);
cb53c626
TI
379#ifdef CONFIG_SND_HDA_POWER_SAVE
380 struct hda_amp_list *loopbacks;
381#endif
1da177e4
LT
382};
383
1da177e4
LT
384
385/*
386 * input MUX handling
387 */
9c7f852e
TI
388static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
389 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
390{
391 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
392 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
393 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
394 if (mux_idx >= spec->num_mux_defs)
395 mux_idx = 0;
396 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
397}
398
9c7f852e
TI
399static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
400 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
401{
402 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
403 struct alc_spec *spec = codec->spec;
404 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
405
406 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
407 return 0;
408}
409
9c7f852e
TI
410static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
411 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
412{
413 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
414 struct alc_spec *spec = codec->spec;
cd896c33 415 const struct hda_input_mux *imux;
1da177e4 416 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 417 unsigned int mux_idx;
e1406348
TI
418 hda_nid_t nid = spec->capsrc_nids ?
419 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4 420
cd896c33
TI
421 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
422 imux = &spec->input_mux[mux_idx];
423
61b9b9b1
HRK
424 if (spec->capture_style &&
425 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
54cbc9ab
TI
426 /* Matrix-mixer style (e.g. ALC882) */
427 unsigned int *cur_val = &spec->cur_mux[adc_idx];
428 unsigned int i, idx;
429
430 idx = ucontrol->value.enumerated.item[0];
431 if (idx >= imux->num_items)
432 idx = imux->num_items - 1;
433 if (*cur_val == idx)
434 return 0;
435 for (i = 0; i < imux->num_items; i++) {
436 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
437 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
438 imux->items[i].index,
439 HDA_AMP_MUTE, v);
440 }
441 *cur_val = idx;
442 return 1;
443 } else {
444 /* MUX style (e.g. ALC880) */
cd896c33 445 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
446 &spec->cur_mux[adc_idx]);
447 }
448}
e9edcee0 449
1da177e4
LT
450/*
451 * channel mode setting
452 */
9c7f852e
TI
453static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
455{
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
458 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
459 spec->num_channel_mode);
1da177e4
LT
460}
461
9c7f852e
TI
462static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
463 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
464{
465 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
466 struct alc_spec *spec = codec->spec;
d2a6d7dc 467 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 468 spec->num_channel_mode,
3b315d70 469 spec->ext_channel_count);
1da177e4
LT
470}
471
9c7f852e
TI
472static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
474{
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
4e195a7b
TI
477 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
478 spec->num_channel_mode,
3b315d70
HM
479 &spec->ext_channel_count);
480 if (err >= 0 && !spec->const_channel_count) {
481 spec->multiout.max_channels = spec->ext_channel_count;
482 if (spec->need_dac_fix)
483 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
484 }
4e195a7b 485 return err;
1da177e4
LT
486}
487
a9430dd8 488/*
4c5186ed 489 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 490 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
491 * being part of a format specifier. Maximum allowed length of a value is
492 * 63 characters plus NULL terminator.
7cf51e48
JW
493 *
494 * Note: some retasking pin complexes seem to ignore requests for input
495 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
496 * are requested. Therefore order this list so that this behaviour will not
497 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
498 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
499 * March 2006.
4c5186ed
JW
500 */
501static char *alc_pin_mode_names[] = {
7cf51e48
JW
502 "Mic 50pc bias", "Mic 80pc bias",
503 "Line in", "Line out", "Headphone out",
4c5186ed
JW
504};
505static unsigned char alc_pin_mode_values[] = {
7cf51e48 506 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
507};
508/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
509 * in the pin being assumed to be exclusively an input or an output pin. In
510 * addition, "input" pins may or may not process the mic bias option
511 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
512 * accept requests for bias as of chip versions up to March 2006) and/or
513 * wiring in the computer.
a9430dd8 514 */
a1e8d2da
JW
515#define ALC_PIN_DIR_IN 0x00
516#define ALC_PIN_DIR_OUT 0x01
517#define ALC_PIN_DIR_INOUT 0x02
518#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
519#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 520
ea1fb29a 521/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
522 * For each direction the minimum and maximum values are given.
523 */
a1e8d2da 524static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
525 { 0, 2 }, /* ALC_PIN_DIR_IN */
526 { 3, 4 }, /* ALC_PIN_DIR_OUT */
527 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
528 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
529 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
530};
531#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
532#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
533#define alc_pin_mode_n_items(_dir) \
534 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
535
9c7f852e
TI
536static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
537 struct snd_ctl_elem_info *uinfo)
a9430dd8 538{
4c5186ed
JW
539 unsigned int item_num = uinfo->value.enumerated.item;
540 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
541
542 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 543 uinfo->count = 1;
4c5186ed
JW
544 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
545
546 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
547 item_num = alc_pin_mode_min(dir);
548 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
549 return 0;
550}
551
9c7f852e
TI
552static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
a9430dd8 554{
4c5186ed 555 unsigned int i;
a9430dd8
JW
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 558 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 559 long *valp = 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
4c5186ed
JW
564 /* Find enumerated value for current pinctl setting */
565 i = alc_pin_mode_min(dir);
9c7f852e 566 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 567 i++;
9c7f852e 568 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
569 return 0;
570}
571
9c7f852e
TI
572static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
573 struct snd_ctl_elem_value *ucontrol)
a9430dd8 574{
4c5186ed 575 signed int change;
a9430dd8
JW
576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
578 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
579 long val = *ucontrol->value.integer.value;
9c7f852e
TI
580 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
581 AC_VERB_GET_PIN_WIDGET_CONTROL,
582 0x00);
a9430dd8 583
f12ab1e0 584 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
585 val = alc_pin_mode_min(dir);
586
587 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
588 if (change) {
589 /* Set pin mode to that requested */
82beb8fd
TI
590 snd_hda_codec_write_cache(codec, nid, 0,
591 AC_VERB_SET_PIN_WIDGET_CONTROL,
592 alc_pin_mode_values[val]);
cdcd9268 593
ea1fb29a 594 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
595 * for the requested pin mode. Enum values of 2 or less are
596 * input modes.
597 *
598 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
599 * reduces noise slightly (particularly on input) so we'll
600 * do it. However, having both input and output buffers
601 * enabled simultaneously doesn't seem to be problematic if
602 * this turns out to be necessary in the future.
cdcd9268
JW
603 */
604 if (val <= 2) {
47fd830a
TI
605 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
606 HDA_AMP_MUTE, HDA_AMP_MUTE);
607 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
608 HDA_AMP_MUTE, 0);
cdcd9268 609 } else {
47fd830a
TI
610 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
611 HDA_AMP_MUTE, HDA_AMP_MUTE);
612 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
613 HDA_AMP_MUTE, 0);
cdcd9268
JW
614 }
615 }
a9430dd8
JW
616 return change;
617}
618
4c5186ed 619#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 620 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
621 .info = alc_pin_mode_info, \
622 .get = alc_pin_mode_get, \
623 .put = alc_pin_mode_put, \
624 .private_value = nid | (dir<<16) }
df694daa 625
5c8f858d
JW
626/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
627 * together using a mask with more than one bit set. This control is
628 * currently used only by the ALC260 test model. At this stage they are not
629 * needed for any "production" models.
630 */
631#ifdef CONFIG_SND_DEBUG
a5ce8890 632#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 633
9c7f852e
TI
634static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
636{
637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
638 hda_nid_t nid = kcontrol->private_value & 0xffff;
639 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
640 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
641 unsigned int val = snd_hda_codec_read(codec, nid, 0,
642 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
643
644 *valp = (val & mask) != 0;
645 return 0;
646}
9c7f852e
TI
647static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
649{
650 signed int change;
651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
652 hda_nid_t nid = kcontrol->private_value & 0xffff;
653 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
654 long val = *ucontrol->value.integer.value;
9c7f852e
TI
655 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
656 AC_VERB_GET_GPIO_DATA,
657 0x00);
5c8f858d
JW
658
659 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
660 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
661 if (val == 0)
5c8f858d
JW
662 gpio_data &= ~mask;
663 else
664 gpio_data |= mask;
82beb8fd
TI
665 snd_hda_codec_write_cache(codec, nid, 0,
666 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
667
668 return change;
669}
670#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
672 .info = alc_gpio_data_info, \
673 .get = alc_gpio_data_get, \
674 .put = alc_gpio_data_put, \
675 .private_value = nid | (mask<<16) }
676#endif /* CONFIG_SND_DEBUG */
677
92621f13
JW
678/* A switch control to allow the enabling of the digital IO pins on the
679 * ALC260. This is incredibly simplistic; the intention of this control is
680 * to provide something in the test model allowing digital outputs to be
681 * identified if present. If models are found which can utilise these
682 * outputs a more complete mixer control can be devised for those models if
683 * necessary.
684 */
685#ifdef CONFIG_SND_DEBUG
a5ce8890 686#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 687
9c7f852e
TI
688static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
690{
691 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
692 hda_nid_t nid = kcontrol->private_value & 0xffff;
693 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
694 long *valp = ucontrol->value.integer.value;
9c7f852e 695 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 696 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
697
698 *valp = (val & mask) != 0;
699 return 0;
700}
9c7f852e
TI
701static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
703{
704 signed int change;
705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706 hda_nid_t nid = kcontrol->private_value & 0xffff;
707 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
708 long val = *ucontrol->value.integer.value;
9c7f852e 709 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 710 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 711 0x00);
92621f13
JW
712
713 /* Set/unset the masked control bit(s) as needed */
9c7f852e 714 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
715 if (val==0)
716 ctrl_data &= ~mask;
717 else
718 ctrl_data |= mask;
82beb8fd
TI
719 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
720 ctrl_data);
92621f13
JW
721
722 return change;
723}
724#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
725 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
726 .info = alc_spdif_ctrl_info, \
727 .get = alc_spdif_ctrl_get, \
728 .put = alc_spdif_ctrl_put, \
729 .private_value = nid | (mask<<16) }
730#endif /* CONFIG_SND_DEBUG */
731
f8225f6d
JW
732/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
733 * Again, this is only used in the ALC26x test models to help identify when
734 * the EAPD line must be asserted for features to work.
735 */
736#ifdef CONFIG_SND_DEBUG
737#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
738
739static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
740 struct snd_ctl_elem_value *ucontrol)
741{
742 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
743 hda_nid_t nid = kcontrol->private_value & 0xffff;
744 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
745 long *valp = ucontrol->value.integer.value;
746 unsigned int val = snd_hda_codec_read(codec, nid, 0,
747 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
748
749 *valp = (val & mask) != 0;
750 return 0;
751}
752
753static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
755{
756 int change;
757 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
758 hda_nid_t nid = kcontrol->private_value & 0xffff;
759 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
760 long val = *ucontrol->value.integer.value;
761 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
762 AC_VERB_GET_EAPD_BTLENABLE,
763 0x00);
764
765 /* Set/unset the masked control bit(s) as needed */
766 change = (!val ? 0 : mask) != (ctrl_data & mask);
767 if (!val)
768 ctrl_data &= ~mask;
769 else
770 ctrl_data |= mask;
771 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
772 ctrl_data);
773
774 return change;
775}
776
777#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
779 .info = alc_eapd_ctrl_info, \
780 .get = alc_eapd_ctrl_get, \
781 .put = alc_eapd_ctrl_put, \
782 .private_value = nid | (mask<<16) }
783#endif /* CONFIG_SND_DEBUG */
784
23f0c048
TI
785/*
786 * set up the input pin config (depending on the given auto-pin type)
787 */
788static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
789 int auto_pin_type)
790{
791 unsigned int val = PIN_IN;
792
793 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
794 unsigned int pincap;
1327a32b 795 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
796 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
797 if (pincap & AC_PINCAP_VREF_80)
798 val = PIN_VREF80;
461c6c3a
TI
799 else if (pincap & AC_PINCAP_VREF_50)
800 val = PIN_VREF50;
801 else if (pincap & AC_PINCAP_VREF_100)
802 val = PIN_VREF100;
803 else if (pincap & AC_PINCAP_VREF_GRD)
804 val = PIN_VREFGRD;
23f0c048
TI
805 }
806 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
807}
808
d88897ea
TI
809/*
810 */
811static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
812{
813 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
814 return;
815 spec->mixers[spec->num_mixers++] = mix;
816}
817
818static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
819{
820 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
821 return;
822 spec->init_verbs[spec->num_init_verbs++] = verb;
823}
824
daead538
TI
825#ifdef CONFIG_PROC_FS
826/*
827 * hook for proc
828 */
829static void print_realtek_coef(struct snd_info_buffer *buffer,
830 struct hda_codec *codec, hda_nid_t nid)
831{
832 int coeff;
833
834 if (nid != 0x20)
835 return;
836 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
837 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
838 coeff = snd_hda_codec_read(codec, nid, 0,
839 AC_VERB_GET_COEF_INDEX, 0);
840 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
841}
842#else
843#define print_realtek_coef NULL
844#endif
845
df694daa
KY
846/*
847 * set up from the preset table
848 */
9c7f852e
TI
849static void setup_preset(struct alc_spec *spec,
850 const struct alc_config_preset *preset)
df694daa
KY
851{
852 int i;
853
854 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 855 add_mixer(spec, preset->mixers[i]);
f9e336f6 856 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
857 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
858 i++)
d88897ea 859 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 860
df694daa
KY
861 spec->channel_mode = preset->channel_mode;
862 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 863 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 864 spec->const_channel_count = preset->const_channel_count;
df694daa 865
3b315d70
HM
866 if (preset->const_channel_count)
867 spec->multiout.max_channels = preset->const_channel_count;
868 else
869 spec->multiout.max_channels = spec->channel_mode[0].channels;
870 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
871
872 spec->multiout.num_dacs = preset->num_dacs;
873 spec->multiout.dac_nids = preset->dac_nids;
874 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 875 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 876 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 877
a1e8d2da 878 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 879 if (!spec->num_mux_defs)
a1e8d2da 880 spec->num_mux_defs = 1;
df694daa
KY
881 spec->input_mux = preset->input_mux;
882
883 spec->num_adc_nids = preset->num_adc_nids;
884 spec->adc_nids = preset->adc_nids;
e1406348 885 spec->capsrc_nids = preset->capsrc_nids;
df694daa 886 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
887
888 spec->unsol_event = preset->unsol_event;
889 spec->init_hook = preset->init_hook;
cb53c626
TI
890#ifdef CONFIG_SND_HDA_POWER_SAVE
891 spec->loopback.amplist = preset->loopbacks;
892#endif
df694daa
KY
893}
894
bc9f98a9
KY
895/* Enable GPIO mask and set output */
896static struct hda_verb alc_gpio1_init_verbs[] = {
897 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
898 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
899 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
900 { }
901};
902
903static struct hda_verb alc_gpio2_init_verbs[] = {
904 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
905 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
906 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
907 { }
908};
909
bdd148a3
KY
910static struct hda_verb alc_gpio3_init_verbs[] = {
911 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
912 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
913 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
914 { }
915};
916
2c3bf9ab
TI
917/*
918 * Fix hardware PLL issue
919 * On some codecs, the analog PLL gating control must be off while
920 * the default value is 1.
921 */
922static void alc_fix_pll(struct hda_codec *codec)
923{
924 struct alc_spec *spec = codec->spec;
925 unsigned int val;
926
927 if (!spec->pll_nid)
928 return;
929 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
930 spec->pll_coef_idx);
931 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
932 AC_VERB_GET_PROC_COEF, 0);
933 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
934 spec->pll_coef_idx);
935 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
936 val & ~(1 << spec->pll_coef_bit));
937}
938
939static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
940 unsigned int coef_idx, unsigned int coef_bit)
941{
942 struct alc_spec *spec = codec->spec;
943 spec->pll_nid = nid;
944 spec->pll_coef_idx = coef_idx;
945 spec->pll_coef_bit = coef_bit;
946 alc_fix_pll(codec);
947}
948
a9fd4f3f 949static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
950{
951 struct alc_spec *spec = codec->spec;
c9b58006 952 unsigned int present;
a9fd4f3f
TI
953 unsigned int nid = spec->autocfg.hp_pins[0];
954 int i;
c9b58006
KY
955
956 /* need to execute and sync at first */
a9fd4f3f
TI
957 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
958 present = snd_hda_codec_read(codec, nid, 0,
c9b58006 959 AC_VERB_GET_PIN_SENSE, 0);
a9fd4f3f
TI
960 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
961 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
962 nid = spec->autocfg.speaker_pins[i];
963 if (!nid)
964 break;
965 snd_hda_codec_write(codec, nid, 0,
966 AC_VERB_SET_PIN_WIDGET_CONTROL,
967 spec->jack_present ? 0 : PIN_OUT);
968 }
c9b58006
KY
969}
970
4605b718 971#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
972static void alc_mic_automute(struct hda_codec *codec)
973{
974 struct alc_spec *spec = codec->spec;
975 unsigned int present;
976 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
977 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
978 unsigned int mix_nid = spec->capsrc_nids[0];
979 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
980
981 capsrc_idx_mic = mic_nid - 0x18;
982 capsrc_idx_fmic = fmic_nid - 0x18;
983 present = snd_hda_codec_read(codec, mic_nid, 0,
984 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
985 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
986 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
987 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
988 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
989 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
990 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
991}
4605b718 992#else
45bdd1c1 993#define alc_mic_automute(codec) do {} while(0) /* NOP */
4605b718 994#endif /* disabled */
7fb0d78f 995
c9b58006
KY
996/* unsolicited event for HP jack sensing */
997static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
998{
999 if (codec->vendor_id == 0x10ec0880)
1000 res >>= 28;
1001 else
1002 res >>= 26;
a9fd4f3f
TI
1003 switch (res) {
1004 case ALC880_HP_EVENT:
1005 alc_automute_pin(codec);
1006 break;
1007 case ALC880_MIC_EVENT:
7fb0d78f 1008 alc_mic_automute(codec);
a9fd4f3f
TI
1009 break;
1010 }
7fb0d78f
KY
1011}
1012
1013static void alc_inithook(struct hda_codec *codec)
1014{
a9fd4f3f 1015 alc_automute_pin(codec);
7fb0d78f 1016 alc_mic_automute(codec);
c9b58006
KY
1017}
1018
f9423e7a
KY
1019/* additional initialization for ALC888 variants */
1020static void alc888_coef_init(struct hda_codec *codec)
1021{
1022 unsigned int tmp;
1023
1024 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1025 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1026 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1027 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1028 /* alc888S-VC */
1029 snd_hda_codec_read(codec, 0x20, 0,
1030 AC_VERB_SET_PROC_COEF, 0x830);
1031 else
1032 /* alc888-VB */
1033 snd_hda_codec_read(codec, 0x20, 0,
1034 AC_VERB_SET_PROC_COEF, 0x3030);
1035}
1036
4a79ba34 1037static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1038{
4a79ba34 1039 unsigned int tmp;
bc9f98a9 1040
4a79ba34
TI
1041 switch (type) {
1042 case ALC_INIT_GPIO1:
bc9f98a9
KY
1043 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1044 break;
4a79ba34 1045 case ALC_INIT_GPIO2:
bc9f98a9
KY
1046 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1047 break;
4a79ba34 1048 case ALC_INIT_GPIO3:
bdd148a3
KY
1049 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1050 break;
4a79ba34 1051 case ALC_INIT_DEFAULT:
bdd148a3 1052 switch (codec->vendor_id) {
c9b58006
KY
1053 case 0x10ec0260:
1054 snd_hda_codec_write(codec, 0x0f, 0,
1055 AC_VERB_SET_EAPD_BTLENABLE, 2);
1056 snd_hda_codec_write(codec, 0x10, 0,
1057 AC_VERB_SET_EAPD_BTLENABLE, 2);
1058 break;
1059 case 0x10ec0262:
bdd148a3
KY
1060 case 0x10ec0267:
1061 case 0x10ec0268:
c9b58006 1062 case 0x10ec0269:
c6e8f2da 1063 case 0x10ec0272:
f9423e7a
KY
1064 case 0x10ec0660:
1065 case 0x10ec0662:
1066 case 0x10ec0663:
c9b58006 1067 case 0x10ec0862:
20a3a05d 1068 case 0x10ec0889:
bdd148a3
KY
1069 snd_hda_codec_write(codec, 0x14, 0,
1070 AC_VERB_SET_EAPD_BTLENABLE, 2);
1071 snd_hda_codec_write(codec, 0x15, 0,
1072 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 1073 break;
bdd148a3 1074 }
c9b58006
KY
1075 switch (codec->vendor_id) {
1076 case 0x10ec0260:
1077 snd_hda_codec_write(codec, 0x1a, 0,
1078 AC_VERB_SET_COEF_INDEX, 7);
1079 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1080 AC_VERB_GET_PROC_COEF, 0);
1081 snd_hda_codec_write(codec, 0x1a, 0,
1082 AC_VERB_SET_COEF_INDEX, 7);
1083 snd_hda_codec_write(codec, 0x1a, 0,
1084 AC_VERB_SET_PROC_COEF,
1085 tmp | 0x2010);
1086 break;
1087 case 0x10ec0262:
1088 case 0x10ec0880:
1089 case 0x10ec0882:
1090 case 0x10ec0883:
1091 case 0x10ec0885:
4a5a4c56 1092 case 0x10ec0887:
20a3a05d 1093 case 0x10ec0889:
c9b58006
KY
1094 snd_hda_codec_write(codec, 0x20, 0,
1095 AC_VERB_SET_COEF_INDEX, 7);
1096 tmp = snd_hda_codec_read(codec, 0x20, 0,
1097 AC_VERB_GET_PROC_COEF, 0);
1098 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1099 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1100 snd_hda_codec_write(codec, 0x20, 0,
1101 AC_VERB_SET_PROC_COEF,
1102 tmp | 0x2010);
1103 break;
f9423e7a 1104 case 0x10ec0888:
4a79ba34 1105 alc888_coef_init(codec);
f9423e7a 1106 break;
c9b58006
KY
1107 case 0x10ec0267:
1108 case 0x10ec0268:
1109 snd_hda_codec_write(codec, 0x20, 0,
1110 AC_VERB_SET_COEF_INDEX, 7);
1111 tmp = snd_hda_codec_read(codec, 0x20, 0,
1112 AC_VERB_GET_PROC_COEF, 0);
1113 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1114 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1115 snd_hda_codec_write(codec, 0x20, 0,
1116 AC_VERB_SET_PROC_COEF,
1117 tmp | 0x3000);
1118 break;
bc9f98a9 1119 }
4a79ba34
TI
1120 break;
1121 }
1122}
1123
1124static void alc_init_auto_hp(struct hda_codec *codec)
1125{
1126 struct alc_spec *spec = codec->spec;
1127
1128 if (!spec->autocfg.hp_pins[0])
1129 return;
1130
1131 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1132 if (spec->autocfg.line_out_pins[0] &&
1133 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1134 spec->autocfg.speaker_pins[0] =
1135 spec->autocfg.line_out_pins[0];
1136 else
1137 return;
1138 }
1139
2a2ed0df
TI
1140 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1141 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1142 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1143 AC_VERB_SET_UNSOLICITED_ENABLE,
1144 AC_USRSP_EN | ALC880_HP_EVENT);
1145 spec->unsol_event = alc_sku_unsol_event;
1146}
1147
1148/* check subsystem ID and set up device-specific initialization;
1149 * return 1 if initialized, 0 if invalid SSID
1150 */
1151/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1152 * 31 ~ 16 : Manufacture ID
1153 * 15 ~ 8 : SKU ID
1154 * 7 ~ 0 : Assembly ID
1155 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1156 */
1157static int alc_subsystem_id(struct hda_codec *codec,
1158 hda_nid_t porta, hda_nid_t porte,
1159 hda_nid_t portd)
1160{
1161 unsigned int ass, tmp, i;
1162 unsigned nid;
1163 struct alc_spec *spec = codec->spec;
1164
1165 ass = codec->subsystem_id & 0xffff;
1166 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1167 goto do_sku;
1168
1169 /* invalid SSID, check the special NID pin defcfg instead */
1170 /*
1171 * 31~30 : port conetcivity
1172 * 29~21 : reserve
1173 * 20 : PCBEEP input
1174 * 19~16 : Check sum (15:1)
1175 * 15~1 : Custom
1176 * 0 : override
1177 */
1178 nid = 0x1d;
1179 if (codec->vendor_id == 0x10ec0260)
1180 nid = 0x17;
1181 ass = snd_hda_codec_get_pincfg(codec, nid);
1182 snd_printd("realtek: No valid SSID, "
1183 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1184 ass, nid);
4a79ba34
TI
1185 if (!(ass & 1) && !(ass & 0x100000))
1186 return 0;
1187 if ((ass >> 30) != 1) /* no physical connection */
1188 return 0;
1189
1190 /* check sum */
1191 tmp = 0;
1192 for (i = 1; i < 16; i++) {
1193 if ((ass >> i) & 1)
1194 tmp++;
1195 }
1196 if (((ass >> 16) & 0xf) != tmp)
1197 return 0;
1198do_sku:
1199 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1200 ass & 0xffff, codec->vendor_id);
1201 /*
1202 * 0 : override
1203 * 1 : Swap Jack
1204 * 2 : 0 --> Desktop, 1 --> Laptop
1205 * 3~5 : External Amplifier control
1206 * 7~6 : Reserved
1207 */
1208 tmp = (ass & 0x38) >> 3; /* external Amp control */
1209 switch (tmp) {
1210 case 1:
1211 spec->init_amp = ALC_INIT_GPIO1;
1212 break;
1213 case 3:
1214 spec->init_amp = ALC_INIT_GPIO2;
1215 break;
1216 case 7:
1217 spec->init_amp = ALC_INIT_GPIO3;
1218 break;
1219 case 5:
1220 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1221 break;
1222 }
ea1fb29a 1223
8c427226 1224 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1225 * when the external headphone out jack is plugged"
1226 */
8c427226 1227 if (!(ass & 0x8000))
4a79ba34 1228 return 1;
c9b58006
KY
1229 /*
1230 * 10~8 : Jack location
1231 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1232 * 14~13: Resvered
1233 * 15 : 1 --> enable the function "Mute internal speaker
1234 * when the external headphone out jack is plugged"
1235 */
c9b58006
KY
1236 if (!spec->autocfg.hp_pins[0]) {
1237 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1238 if (tmp == 0)
1239 spec->autocfg.hp_pins[0] = porta;
1240 else if (tmp == 1)
1241 spec->autocfg.hp_pins[0] = porte;
1242 else if (tmp == 2)
1243 spec->autocfg.hp_pins[0] = portd;
1244 else
4a79ba34 1245 return 1;
c9b58006
KY
1246 }
1247
4a79ba34
TI
1248 alc_init_auto_hp(codec);
1249 return 1;
1250}
ea1fb29a 1251
4a79ba34
TI
1252static void alc_ssid_check(struct hda_codec *codec,
1253 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1254{
1255 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1256 struct alc_spec *spec = codec->spec;
1257 snd_printd("realtek: "
1258 "Enable default setup for auto mode as fallback\n");
1259 spec->init_amp = ALC_INIT_DEFAULT;
1260 alc_init_auto_hp(codec);
1261 }
bc9f98a9
KY
1262}
1263
f95474ec
TI
1264/*
1265 * Fix-up pin default configurations
1266 */
1267
1268struct alc_pincfg {
1269 hda_nid_t nid;
1270 u32 val;
1271};
1272
1273static void alc_fix_pincfg(struct hda_codec *codec,
1274 const struct snd_pci_quirk *quirk,
1275 const struct alc_pincfg **pinfix)
1276{
1277 const struct alc_pincfg *cfg;
1278
1279 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1280 if (!quirk)
1281 return;
1282
1283 cfg = pinfix[quirk->value];
0e8a21b5
TI
1284 for (; cfg->nid; cfg++)
1285 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
f95474ec
TI
1286}
1287
ef8ef5fb
VP
1288/*
1289 * ALC888
1290 */
1291
1292/*
1293 * 2ch mode
1294 */
1295static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1296/* Mic-in jack as mic in */
1297 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1298 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1299/* Line-in jack as Line in */
1300 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1301 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1302/* Line-Out as Front */
1303 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1304 { } /* end */
1305};
1306
1307/*
1308 * 4ch mode
1309 */
1310static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1311/* Mic-in jack as mic in */
1312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1314/* Line-in jack as Surround */
1315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1317/* Line-Out as Front */
1318 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1319 { } /* end */
1320};
1321
1322/*
1323 * 6ch mode
1324 */
1325static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1326/* Mic-in jack as CLFE */
1327 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1328 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1329/* Line-in jack as Surround */
1330 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1331 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1332/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1333 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1334 { } /* end */
1335};
1336
1337/*
1338 * 8ch mode
1339 */
1340static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1341/* Mic-in jack as CLFE */
1342 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1343 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1344/* Line-in jack as Surround */
1345 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1346 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1347/* Line-Out as Side */
1348 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1349 { } /* end */
1350};
1351
1352static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1353 { 2, alc888_4ST_ch2_intel_init },
1354 { 4, alc888_4ST_ch4_intel_init },
1355 { 6, alc888_4ST_ch6_intel_init },
1356 { 8, alc888_4ST_ch8_intel_init },
1357};
1358
1359/*
1360 * ALC888 Fujitsu Siemens Amillo xa3530
1361 */
1362
1363static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1364/* Front Mic: set to PIN_IN (empty by default) */
1365 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1366/* Connect Internal HP to Front */
1367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1370/* Connect Bass HP to Front */
1371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1374/* Connect Line-Out side jack (SPDIF) to Side */
1375 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1377 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1378/* Connect Mic jack to CLFE */
1379 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1382/* Connect Line-in jack to Surround */
1383 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1384 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1385 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1386/* Connect HP out jack to Front */
1387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1389 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1390/* Enable unsolicited event for HP jack and Line-out jack */
1391 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1392 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1393 {}
1394};
1395
a9fd4f3f 1396static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1397{
a9fd4f3f
TI
1398 struct alc_spec *spec = codec->spec;
1399 unsigned int val, mute;
1400 hda_nid_t nid;
1401 int i;
1402
1403 spec->jack_present = 0;
1404 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1405 nid = spec->autocfg.hp_pins[i];
1406 if (!nid)
1407 break;
1408 val = snd_hda_codec_read(codec, nid, 0,
1409 AC_VERB_GET_PIN_SENSE, 0);
1410 if (val & AC_PINSENSE_PRESENCE) {
1411 spec->jack_present = 1;
1412 break;
1413 }
1414 }
1415
1416 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1417 /* Toggle internal speakers muting */
a9fd4f3f
TI
1418 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1419 nid = spec->autocfg.speaker_pins[i];
1420 if (!nid)
1421 break;
1422 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1423 HDA_AMP_MUTE, mute);
1424 }
ef8ef5fb
VP
1425}
1426
a9fd4f3f
TI
1427static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1428 unsigned int res)
ef8ef5fb 1429{
a9fd4f3f
TI
1430 if (codec->vendor_id == 0x10ec0880)
1431 res >>= 28;
1432 else
1433 res >>= 26;
1434 if (res == ALC880_HP_EVENT)
1435 alc_automute_amp(codec);
ef8ef5fb
VP
1436}
1437
a9fd4f3f
TI
1438static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1439{
1440 struct alc_spec *spec = codec->spec;
1441
1442 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1443 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1444 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1445 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1446 alc_automute_amp(codec);
1447}
ef8ef5fb 1448
5b2d1eca
VP
1449/*
1450 * ALC888 Acer Aspire 4930G model
1451 */
1452
1453static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1454/* Front Mic: set to PIN_IN (empty by default) */
1455 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1456/* Unselect Front Mic by default in input mixer 3 */
1457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1458/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1459 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1460/* Connect Internal HP to front */
1461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1462 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1464/* Connect HP out to front */
1465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1468 { }
1469};
1470
3b315d70 1471/*
018df418 1472 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1473 */
1474
018df418 1475static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1476/* Front Mic: set to PIN_IN (empty by default) */
1477 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1478/* Unselect Front Mic by default in input mixer 3 */
1479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1480/* Enable unsolicited event for HP jack */
1481 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1482/* Connect Internal Front to Front */
1483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1486/* Connect Internal Rear to Rear */
1487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1488 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1489 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1490/* Connect Internal CLFE to CLFE */
1491 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1494/* Connect HP out to Front */
018df418 1495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1498/* Enable all DACs */
1499/* DAC DISABLE/MUTE 1? */
1500/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1501 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1502 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1503/* DAC DISABLE/MUTE 2? */
1504/* some bit here disables the other DACs. Init=0x4900 */
1505 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1506 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1507/* Enable amplifiers */
1508 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1509 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
018df418
HM
1510/* DMIC fix
1511 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1512 * which makes the stereo useless. However, either the mic or the ALC889
1513 * makes the signal become a difference/sum signal instead of standard
1514 * stereo, which is annoying. So instead we flip this bit which makes the
1515 * codec replicate the sum signal to both channels, turning it into a
1516 * normal mono mic.
1517 */
1518/* DMIC_CONTROL? Init value = 0x0001 */
1519 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1520 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1521 { }
1522};
1523
ef8ef5fb 1524static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1525 /* Front mic only available on one ADC */
1526 {
1527 .num_items = 4,
1528 .items = {
1529 { "Mic", 0x0 },
1530 { "Line", 0x2 },
1531 { "CD", 0x4 },
1532 { "Front Mic", 0xb },
1533 },
1534 },
1535 {
1536 .num_items = 3,
1537 .items = {
1538 { "Mic", 0x0 },
1539 { "Line", 0x2 },
1540 { "CD", 0x4 },
1541 },
1542 }
1543};
1544
018df418
HM
1545static struct hda_input_mux alc889_capture_sources[3] = {
1546 /* Digital mic only available on first "ADC" */
1547 {
1548 .num_items = 5,
1549 .items = {
1550 { "Mic", 0x0 },
1551 { "Line", 0x2 },
1552 { "CD", 0x4 },
1553 { "Front Mic", 0xb },
1554 { "Input Mix", 0xa },
1555 },
1556 },
1557 {
1558 .num_items = 4,
1559 .items = {
1560 { "Mic", 0x0 },
1561 { "Line", 0x2 },
1562 { "CD", 0x4 },
1563 { "Input Mix", 0xa },
1564 },
1565 },
1566 {
1567 .num_items = 4,
1568 .items = {
1569 { "Mic", 0x0 },
1570 { "Line", 0x2 },
1571 { "CD", 0x4 },
1572 { "Input Mix", 0xa },
1573 },
1574 }
1575};
1576
ef8ef5fb 1577static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1578 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1579 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1580 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1581 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1582 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1583 HDA_OUTPUT),
1584 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1585 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1586 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1587 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1588 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1589 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1590 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1591 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1592 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1593 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1594 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1595 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1596 { } /* end */
1597};
1598
a9fd4f3f 1599static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
5b2d1eca 1600{
a9fd4f3f 1601 struct alc_spec *spec = codec->spec;
5b2d1eca 1602
a9fd4f3f
TI
1603 spec->autocfg.hp_pins[0] = 0x15;
1604 spec->autocfg.speaker_pins[0] = 0x14;
1605 alc_automute_amp(codec);
5b2d1eca
VP
1606}
1607
018df418 1608static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
3b315d70
HM
1609{
1610 struct alc_spec *spec = codec->spec;
1611
1612 spec->autocfg.hp_pins[0] = 0x15;
1613 spec->autocfg.speaker_pins[0] = 0x14;
1614 spec->autocfg.speaker_pins[1] = 0x16;
1615 spec->autocfg.speaker_pins[2] = 0x1b;
1616 alc_automute_amp(codec);
1617}
1618
1da177e4 1619/*
e9edcee0
TI
1620 * ALC880 3-stack model
1621 *
1622 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1623 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1624 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1625 */
1626
e9edcee0
TI
1627static hda_nid_t alc880_dac_nids[4] = {
1628 /* front, rear, clfe, rear_surr */
1629 0x02, 0x05, 0x04, 0x03
1630};
1631
1632static hda_nid_t alc880_adc_nids[3] = {
1633 /* ADC0-2 */
1634 0x07, 0x08, 0x09,
1635};
1636
1637/* The datasheet says the node 0x07 is connected from inputs,
1638 * but it shows zero connection in the real implementation on some devices.
df694daa 1639 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1640 */
e9edcee0
TI
1641static hda_nid_t alc880_adc_nids_alt[2] = {
1642 /* ADC1-2 */
1643 0x08, 0x09,
1644};
1645
1646#define ALC880_DIGOUT_NID 0x06
1647#define ALC880_DIGIN_NID 0x0a
1648
1649static struct hda_input_mux alc880_capture_source = {
1650 .num_items = 4,
1651 .items = {
1652 { "Mic", 0x0 },
1653 { "Front Mic", 0x3 },
1654 { "Line", 0x2 },
1655 { "CD", 0x4 },
1656 },
1657};
1658
1659/* channel source setting (2/6 channel selection for 3-stack) */
1660/* 2ch mode */
1661static struct hda_verb alc880_threestack_ch2_init[] = {
1662 /* set line-in to input, mute it */
1663 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1664 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1665 /* set mic-in to input vref 80%, mute it */
1666 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1667 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1668 { } /* end */
1669};
1670
1671/* 6ch mode */
1672static struct hda_verb alc880_threestack_ch6_init[] = {
1673 /* set line-in to output, unmute it */
1674 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1675 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1676 /* set mic-in to output, unmute it */
1677 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1678 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1679 { } /* end */
1680};
1681
d2a6d7dc 1682static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1683 { 2, alc880_threestack_ch2_init },
1684 { 6, alc880_threestack_ch6_init },
1685};
1686
c8b6bf9b 1687static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1688 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1689 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1690 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1691 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1692 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1693 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1694 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1695 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1696 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1697 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1698 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1699 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1701 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1702 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1703 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1705 {
1706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1707 .name = "Channel Mode",
df694daa
KY
1708 .info = alc_ch_mode_info,
1709 .get = alc_ch_mode_get,
1710 .put = alc_ch_mode_put,
e9edcee0
TI
1711 },
1712 { } /* end */
1713};
1714
1715/* capture mixer elements */
f9e336f6
TI
1716static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1717 struct snd_ctl_elem_info *uinfo)
1718{
1719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1720 struct alc_spec *spec = codec->spec;
1721 int err;
1da177e4 1722
5a9e02e9 1723 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1724 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1725 HDA_INPUT);
1726 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1727 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1728 return err;
1729}
1730
1731static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1732 unsigned int size, unsigned int __user *tlv)
1733{
1734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1735 struct alc_spec *spec = codec->spec;
1736 int err;
1da177e4 1737
5a9e02e9 1738 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1739 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1740 HDA_INPUT);
1741 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1742 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1743 return err;
1744}
1745
1746typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1747 struct snd_ctl_elem_value *ucontrol);
1748
1749static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1750 struct snd_ctl_elem_value *ucontrol,
1751 getput_call_t func)
1752{
1753 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1754 struct alc_spec *spec = codec->spec;
1755 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1756 int err;
1757
5a9e02e9 1758 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1759 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1760 3, 0, HDA_INPUT);
1761 err = func(kcontrol, ucontrol);
5a9e02e9 1762 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1763 return err;
1764}
1765
1766static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1767 struct snd_ctl_elem_value *ucontrol)
1768{
1769 return alc_cap_getput_caller(kcontrol, ucontrol,
1770 snd_hda_mixer_amp_volume_get);
1771}
1772
1773static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1774 struct snd_ctl_elem_value *ucontrol)
1775{
1776 return alc_cap_getput_caller(kcontrol, ucontrol,
1777 snd_hda_mixer_amp_volume_put);
1778}
1779
1780/* capture mixer elements */
1781#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1782
1783static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1784 struct snd_ctl_elem_value *ucontrol)
1785{
1786 return alc_cap_getput_caller(kcontrol, ucontrol,
1787 snd_hda_mixer_amp_switch_get);
1788}
1789
1790static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1791 struct snd_ctl_elem_value *ucontrol)
1792{
1793 return alc_cap_getput_caller(kcontrol, ucontrol,
1794 snd_hda_mixer_amp_switch_put);
1795}
1796
a23b688f 1797#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
1798 { \
1799 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1800 .name = "Capture Switch", \
1801 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1802 .count = num, \
1803 .info = alc_cap_sw_info, \
1804 .get = alc_cap_sw_get, \
1805 .put = alc_cap_sw_put, \
1806 }, \
1807 { \
1808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1809 .name = "Capture Volume", \
1810 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1811 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1812 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1813 .count = num, \
1814 .info = alc_cap_vol_info, \
1815 .get = alc_cap_vol_get, \
1816 .put = alc_cap_vol_put, \
1817 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
1818 }
1819
1820#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
1821 { \
1822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1823 /* .name = "Capture Source", */ \
1824 .name = "Input Source", \
1825 .count = num, \
1826 .info = alc_mux_enum_info, \
1827 .get = alc_mux_enum_get, \
1828 .put = alc_mux_enum_put, \
a23b688f
TI
1829 }
1830
1831#define DEFINE_CAPMIX(num) \
1832static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1833 _DEFINE_CAPMIX(num), \
1834 _DEFINE_CAPSRC(num), \
1835 { } /* end */ \
1836}
1837
1838#define DEFINE_CAPMIX_NOSRC(num) \
1839static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1840 _DEFINE_CAPMIX(num), \
1841 { } /* end */ \
f9e336f6
TI
1842}
1843
1844/* up to three ADCs */
1845DEFINE_CAPMIX(1);
1846DEFINE_CAPMIX(2);
1847DEFINE_CAPMIX(3);
a23b688f
TI
1848DEFINE_CAPMIX_NOSRC(1);
1849DEFINE_CAPMIX_NOSRC(2);
1850DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
1851
1852/*
1853 * ALC880 5-stack model
1854 *
9c7f852e
TI
1855 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1856 * Side = 0x02 (0xd)
e9edcee0
TI
1857 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1858 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1859 */
1860
1861/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1862static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1863 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1864 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1865 { } /* end */
1866};
1867
e9edcee0
TI
1868/* channel source setting (6/8 channel selection for 5-stack) */
1869/* 6ch mode */
1870static struct hda_verb alc880_fivestack_ch6_init[] = {
1871 /* set line-in to input, mute it */
1872 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1873 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1874 { } /* end */
1875};
1876
e9edcee0
TI
1877/* 8ch mode */
1878static struct hda_verb alc880_fivestack_ch8_init[] = {
1879 /* set line-in to output, unmute it */
1880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1882 { } /* end */
1883};
1884
d2a6d7dc 1885static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1886 { 6, alc880_fivestack_ch6_init },
1887 { 8, alc880_fivestack_ch8_init },
1888};
1889
1890
1891/*
1892 * ALC880 6-stack model
1893 *
9c7f852e
TI
1894 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1895 * Side = 0x05 (0x0f)
e9edcee0
TI
1896 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1897 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1898 */
1899
1900static hda_nid_t alc880_6st_dac_nids[4] = {
1901 /* front, rear, clfe, rear_surr */
1902 0x02, 0x03, 0x04, 0x05
f12ab1e0 1903};
e9edcee0
TI
1904
1905static struct hda_input_mux alc880_6stack_capture_source = {
1906 .num_items = 4,
1907 .items = {
1908 { "Mic", 0x0 },
1909 { "Front Mic", 0x1 },
1910 { "Line", 0x2 },
1911 { "CD", 0x4 },
1912 },
1913};
1914
1915/* fixed 8-channels */
d2a6d7dc 1916static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1917 { 8, NULL },
1918};
1919
c8b6bf9b 1920static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1921 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1922 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1923 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1924 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1925 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1926 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1927 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1928 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1929 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1930 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1931 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1932 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1933 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1934 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1937 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1938 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
1939 {
1940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1941 .name = "Channel Mode",
df694daa
KY
1942 .info = alc_ch_mode_info,
1943 .get = alc_ch_mode_get,
1944 .put = alc_ch_mode_put,
16ded525
TI
1945 },
1946 { } /* end */
1947};
1948
e9edcee0
TI
1949
1950/*
1951 * ALC880 W810 model
1952 *
1953 * W810 has rear IO for:
1954 * Front (DAC 02)
1955 * Surround (DAC 03)
1956 * Center/LFE (DAC 04)
1957 * Digital out (06)
1958 *
1959 * The system also has a pair of internal speakers, and a headphone jack.
1960 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 1961 *
e9edcee0
TI
1962 * There is a variable resistor to control the speaker or headphone
1963 * volume. This is a hardware-only device without a software API.
1964 *
1965 * Plugging headphones in will disable the internal speakers. This is
1966 * implemented in hardware, not via the driver using jack sense. In
1967 * a similar fashion, plugging into the rear socket marked "front" will
1968 * disable both the speakers and headphones.
1969 *
1970 * For input, there's a microphone jack, and an "audio in" jack.
1971 * These may not do anything useful with this driver yet, because I
1972 * haven't setup any initialization verbs for these yet...
1973 */
1974
1975static hda_nid_t alc880_w810_dac_nids[3] = {
1976 /* front, rear/surround, clfe */
1977 0x02, 0x03, 0x04
16ded525
TI
1978};
1979
e9edcee0 1980/* fixed 6 channels */
d2a6d7dc 1981static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1982 { 6, NULL }
1983};
1984
1985/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1986static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1987 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1988 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1989 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1990 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1991 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1995 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1996 { } /* end */
1997};
1998
1999
2000/*
2001 * Z710V model
2002 *
2003 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2004 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2005 * Line = 0x1a
e9edcee0
TI
2006 */
2007
2008static hda_nid_t alc880_z71v_dac_nids[1] = {
2009 0x02
2010};
2011#define ALC880_Z71V_HP_DAC 0x03
2012
2013/* fixed 2 channels */
d2a6d7dc 2014static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2015 { 2, NULL }
2016};
2017
c8b6bf9b 2018static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2019 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2020 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2021 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2022 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2023 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2024 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2025 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2026 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2027 { } /* end */
2028};
2029
e9edcee0 2030
e9edcee0
TI
2031/*
2032 * ALC880 F1734 model
2033 *
2034 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2035 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2036 */
2037
2038static hda_nid_t alc880_f1734_dac_nids[1] = {
2039 0x03
2040};
2041#define ALC880_F1734_HP_DAC 0x02
2042
c8b6bf9b 2043static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2044 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2045 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2046 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2047 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2050 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2051 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2052 { } /* end */
2053};
2054
937b4160
TI
2055static struct hda_input_mux alc880_f1734_capture_source = {
2056 .num_items = 2,
2057 .items = {
2058 { "Mic", 0x1 },
2059 { "CD", 0x4 },
2060 },
2061};
2062
e9edcee0 2063
e9edcee0
TI
2064/*
2065 * ALC880 ASUS model
2066 *
2067 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2068 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2069 * Mic = 0x18, Line = 0x1a
2070 */
2071
2072#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2073#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2074
c8b6bf9b 2075static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2076 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2077 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2078 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2079 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2080 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2081 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2082 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2083 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2084 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2085 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2086 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2087 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2088 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2090 {
2091 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2092 .name = "Channel Mode",
df694daa
KY
2093 .info = alc_ch_mode_info,
2094 .get = alc_ch_mode_get,
2095 .put = alc_ch_mode_put,
16ded525
TI
2096 },
2097 { } /* end */
2098};
e9edcee0 2099
e9edcee0
TI
2100/*
2101 * ALC880 ASUS W1V model
2102 *
2103 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2104 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2105 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2106 */
2107
2108/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2109static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2110 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2111 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2112 { } /* end */
2113};
2114
df694daa
KY
2115/* TCL S700 */
2116static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2117 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2118 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2119 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2120 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2121 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2124 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2125 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2126 { } /* end */
2127};
2128
ccc656ce
KY
2129/* Uniwill */
2130static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2131 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2132 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2133 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2134 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2135 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2136 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2138 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2139 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2140 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2141 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2142 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2147 {
2148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2149 .name = "Channel Mode",
2150 .info = alc_ch_mode_info,
2151 .get = alc_ch_mode_get,
2152 .put = alc_ch_mode_put,
2153 },
2154 { } /* end */
2155};
2156
2cf9f0fc
TD
2157static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2158 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2159 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2160 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2161 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2162 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2163 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2164 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2165 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2166 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2167 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2168 { } /* end */
2169};
2170
ccc656ce 2171static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2172 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2173 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2174 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2175 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2178 { } /* end */
2179};
2180
2134ea4f
TI
2181/*
2182 * virtual master controls
2183 */
2184
2185/*
2186 * slave controls for virtual master
2187 */
2188static const char *alc_slave_vols[] = {
2189 "Front Playback Volume",
2190 "Surround Playback Volume",
2191 "Center Playback Volume",
2192 "LFE Playback Volume",
2193 "Side Playback Volume",
2194 "Headphone Playback Volume",
2195 "Speaker Playback Volume",
2196 "Mono Playback Volume",
2134ea4f 2197 "Line-Out Playback Volume",
26f5df26 2198 "PCM Playback Volume",
2134ea4f
TI
2199 NULL,
2200};
2201
2202static const char *alc_slave_sws[] = {
2203 "Front Playback Switch",
2204 "Surround Playback Switch",
2205 "Center Playback Switch",
2206 "LFE Playback Switch",
2207 "Side Playback Switch",
2208 "Headphone Playback Switch",
2209 "Speaker Playback Switch",
2210 "Mono Playback Switch",
edb54a55 2211 "IEC958 Playback Switch",
2134ea4f
TI
2212 NULL,
2213};
2214
1da177e4 2215/*
e9edcee0 2216 * build control elements
1da177e4 2217 */
603c4019
TI
2218
2219static void alc_free_kctls(struct hda_codec *codec);
2220
45bdd1c1
TI
2221/* additional beep mixers; the actual parameters are overwritten at build */
2222static struct snd_kcontrol_new alc_beep_mixer[] = {
2223 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2224 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2225 { } /* end */
2226};
2227
1da177e4
LT
2228static int alc_build_controls(struct hda_codec *codec)
2229{
2230 struct alc_spec *spec = codec->spec;
2231 int err;
2232 int i;
2233
2234 for (i = 0; i < spec->num_mixers; i++) {
2235 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2236 if (err < 0)
2237 return err;
2238 }
f9e336f6
TI
2239 if (spec->cap_mixer) {
2240 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2241 if (err < 0)
2242 return err;
2243 }
1da177e4 2244 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2245 err = snd_hda_create_spdif_out_ctls(codec,
2246 spec->multiout.dig_out_nid);
1da177e4
LT
2247 if (err < 0)
2248 return err;
e64f14f4
TI
2249 if (!spec->no_analog) {
2250 err = snd_hda_create_spdif_share_sw(codec,
2251 &spec->multiout);
2252 if (err < 0)
2253 return err;
2254 spec->multiout.share_spdif = 1;
2255 }
1da177e4
LT
2256 }
2257 if (spec->dig_in_nid) {
2258 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2259 if (err < 0)
2260 return err;
2261 }
2134ea4f 2262
45bdd1c1
TI
2263 /* create beep controls if needed */
2264 if (spec->beep_amp) {
2265 struct snd_kcontrol_new *knew;
2266 for (knew = alc_beep_mixer; knew->name; knew++) {
2267 struct snd_kcontrol *kctl;
2268 kctl = snd_ctl_new1(knew, codec);
2269 if (!kctl)
2270 return -ENOMEM;
2271 kctl->private_value = spec->beep_amp;
2272 err = snd_hda_ctl_add(codec, kctl);
2273 if (err < 0)
2274 return err;
2275 }
2276 }
2277
2134ea4f 2278 /* if we have no master control, let's create it */
e64f14f4
TI
2279 if (!spec->no_analog &&
2280 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2281 unsigned int vmaster_tlv[4];
2134ea4f 2282 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2283 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2284 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2285 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2286 if (err < 0)
2287 return err;
2288 }
e64f14f4
TI
2289 if (!spec->no_analog &&
2290 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2291 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2292 NULL, alc_slave_sws);
2293 if (err < 0)
2294 return err;
2295 }
2296
603c4019 2297 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
2298 return 0;
2299}
2300
e9edcee0 2301
1da177e4
LT
2302/*
2303 * initialize the codec volumes, etc
2304 */
2305
e9edcee0
TI
2306/*
2307 * generic initialization of ADC, input mixers and output mixers
2308 */
2309static struct hda_verb alc880_volume_init_verbs[] = {
2310 /*
2311 * Unmute ADC0-2 and set the default input to mic-in
2312 */
71fe7b82 2313 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2314 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2315 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2316 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2317 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2318 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2319
e9edcee0
TI
2320 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2321 * mixer widget
9c7f852e
TI
2322 * Note: PASD motherboards uses the Line In 2 as the input for front
2323 * panel mic (mic 2)
1da177e4 2324 */
e9edcee0 2325 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2327 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2328 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2329 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2330 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2331 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2332 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2333
e9edcee0
TI
2334 /*
2335 * Set up output mixers (0x0c - 0x0f)
1da177e4 2336 */
e9edcee0
TI
2337 /* set vol=0 to output mixers */
2338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2339 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2340 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2342 /* set up input amps for analog loopback */
2343 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2350 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2351 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2352
2353 { }
2354};
2355
e9edcee0
TI
2356/*
2357 * 3-stack pin configuration:
2358 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2359 */
2360static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2361 /*
2362 * preset connection lists of input pins
2363 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2364 */
2365 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2366 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2367 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2368
2369 /*
2370 * Set pin mode and muting
2371 */
2372 /* set front pin widgets 0x14 for output */
05acb863 2373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2376 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2377 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2378 /* Mic2 (as headphone out) for HP output */
2379 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2380 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2381 /* Line In pin widget for input */
05acb863 2382 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2383 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2384 /* Line2 (as front mic) pin widget for input and vref at 80% */
2385 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2386 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2387 /* CD pin widget for input */
05acb863 2388 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2389
e9edcee0
TI
2390 { }
2391};
1da177e4 2392
e9edcee0
TI
2393/*
2394 * 5-stack pin configuration:
2395 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2396 * line-in/side = 0x1a, f-mic = 0x1b
2397 */
2398static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2399 /*
2400 * preset connection lists of input pins
2401 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2402 */
e9edcee0
TI
2403 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2404 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2405
e9edcee0
TI
2406 /*
2407 * Set pin mode and muting
1da177e4 2408 */
e9edcee0
TI
2409 /* set pin widgets 0x14-0x17 for output */
2410 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2412 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2413 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414 /* unmute pins for output (no gain on this amp) */
2415 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2416 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2417 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2419
2420 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2421 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2422 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2423 /* Mic2 (as headphone out) for HP output */
2424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2426 /* Line In pin widget for input */
2427 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2428 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2429 /* Line2 (as front mic) pin widget for input and vref at 80% */
2430 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2431 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2432 /* CD pin widget for input */
2433 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2434
2435 { }
2436};
2437
e9edcee0
TI
2438/*
2439 * W810 pin configuration:
2440 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2441 */
2442static struct hda_verb alc880_pin_w810_init_verbs[] = {
2443 /* hphone/speaker input selector: front DAC */
2444 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2445
05acb863 2446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2448 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2450 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2451 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2452
e9edcee0 2453 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2454 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2455
1da177e4
LT
2456 { }
2457};
2458
e9edcee0
TI
2459/*
2460 * Z71V pin configuration:
2461 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2462 */
2463static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2465 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2467 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2468
16ded525 2469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2470 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2471 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2472 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2473
2474 { }
2475};
2476
e9edcee0
TI
2477/*
2478 * 6-stack pin configuration:
9c7f852e
TI
2479 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2480 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2481 */
2482static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2483 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2484
16ded525 2485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2490 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2493
16ded525 2494 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2495 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2498 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2499 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2501 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2502 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2503
e9edcee0
TI
2504 { }
2505};
2506
ccc656ce
KY
2507/*
2508 * Uniwill pin configuration:
2509 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2510 * line = 0x1a
2511 */
2512static struct hda_verb alc880_uniwill_init_verbs[] = {
2513 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2514
2515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2519 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2520 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2522 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2525 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2527 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2528 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2529
2530 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2531 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2533 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2534 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2535 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2536 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2537 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2538 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2539
2540 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2541 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2542
2543 { }
2544};
2545
2546/*
2547* Uniwill P53
ea1fb29a 2548* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2549 */
2550static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2551 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2552
2553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2557 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2558 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2563 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2564 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2565
2566 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2568 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2570 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2572
2573 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2574 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2575
2576 { }
2577};
2578
2cf9f0fc
TD
2579static struct hda_verb alc880_beep_init_verbs[] = {
2580 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2581 { }
2582};
2583
458a4fab
TI
2584/* auto-toggle front mic */
2585static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2586{
2587 unsigned int present;
2588 unsigned char bits;
ccc656ce
KY
2589
2590 present = snd_hda_codec_read(codec, 0x18, 0,
2591 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2592 bits = present ? HDA_AMP_MUTE : 0;
2593 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2594}
2595
a9fd4f3f 2596static void alc880_uniwill_init_hook(struct hda_codec *codec)
458a4fab 2597{
a9fd4f3f
TI
2598 struct alc_spec *spec = codec->spec;
2599
2600 spec->autocfg.hp_pins[0] = 0x14;
2601 spec->autocfg.speaker_pins[0] = 0x15;
2602 spec->autocfg.speaker_pins[0] = 0x16;
2603 alc_automute_amp(codec);
458a4fab 2604 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2605}
2606
2607static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2608 unsigned int res)
2609{
2610 /* Looks like the unsol event is incompatible with the standard
2611 * definition. 4bit tag is placed at 28 bit!
2612 */
458a4fab 2613 switch (res >> 28) {
458a4fab
TI
2614 case ALC880_MIC_EVENT:
2615 alc880_uniwill_mic_automute(codec);
2616 break;
a9fd4f3f
TI
2617 default:
2618 alc_automute_amp_unsol_event(codec, res);
2619 break;
458a4fab 2620 }
ccc656ce
KY
2621}
2622
a9fd4f3f 2623static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
ccc656ce 2624{
a9fd4f3f 2625 struct alc_spec *spec = codec->spec;
ccc656ce 2626
a9fd4f3f
TI
2627 spec->autocfg.hp_pins[0] = 0x14;
2628 spec->autocfg.speaker_pins[0] = 0x15;
2629 alc_automute_amp(codec);
ccc656ce
KY
2630}
2631
2632static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2633{
2634 unsigned int present;
ea1fb29a 2635
ccc656ce 2636 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2637 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2638 present &= HDA_AMP_VOLMASK;
2639 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2640 HDA_AMP_VOLMASK, present);
2641 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2642 HDA_AMP_VOLMASK, present);
ccc656ce 2643}
47fd830a 2644
ccc656ce
KY
2645static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2646 unsigned int res)
2647{
2648 /* Looks like the unsol event is incompatible with the standard
2649 * definition. 4bit tag is placed at 28 bit!
2650 */
f12ab1e0 2651 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 2652 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
2653 else
2654 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
2655}
2656
e9edcee0
TI
2657/*
2658 * F1734 pin configuration:
2659 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2660 */
2661static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2662 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2663 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2664 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2665 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2666 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2667
e9edcee0 2668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2669 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2670 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2672
e9edcee0
TI
2673 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2674 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2675 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2676 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2677 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2678 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2679 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2680 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2681 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2682
937b4160
TI
2683 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2684 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2685
dfc0ff62
TI
2686 { }
2687};
2688
e9edcee0
TI
2689/*
2690 * ASUS pin configuration:
2691 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2692 */
2693static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2694 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2695 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2696 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2697 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2698
2699 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2700 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2701 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2702 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2703 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2704 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2705 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2706 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2707
2708 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2709 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2710 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2712 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2714 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2715 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2716 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2717
e9edcee0
TI
2718 { }
2719};
16ded525 2720
e9edcee0 2721/* Enable GPIO mask and set output */
bc9f98a9
KY
2722#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2723#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
2724
2725/* Clevo m520g init */
2726static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2727 /* headphone output */
2728 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2729 /* line-out */
2730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2732 /* Line-in */
2733 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2734 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2735 /* CD */
2736 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2737 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2738 /* Mic1 (rear panel) */
2739 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2741 /* Mic2 (front panel) */
2742 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2743 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2744 /* headphone */
2745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2746 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2747 /* change to EAPD mode */
2748 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2749 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2750
2751 { }
16ded525
TI
2752};
2753
df694daa 2754static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2755 /* change to EAPD mode */
2756 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2757 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2758
df694daa
KY
2759 /* Headphone output */
2760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2761 /* Front output*/
2762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2763 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2764
2765 /* Line In pin widget for input */
2766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2767 /* CD pin widget for input */
2768 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2769 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2771
2772 /* change to EAPD mode */
2773 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2774 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2775
2776 { }
2777};
16ded525 2778
e9edcee0 2779/*
ae6b813a
TI
2780 * LG m1 express dual
2781 *
2782 * Pin assignment:
2783 * Rear Line-In/Out (blue): 0x14
2784 * Build-in Mic-In: 0x15
2785 * Speaker-out: 0x17
2786 * HP-Out (green): 0x1b
2787 * Mic-In/Out (red): 0x19
2788 * SPDIF-Out: 0x1e
2789 */
2790
2791/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2792static hda_nid_t alc880_lg_dac_nids[3] = {
2793 0x05, 0x02, 0x03
2794};
2795
2796/* seems analog CD is not working */
2797static struct hda_input_mux alc880_lg_capture_source = {
2798 .num_items = 3,
2799 .items = {
2800 { "Mic", 0x1 },
2801 { "Line", 0x5 },
2802 { "Internal Mic", 0x6 },
2803 },
2804};
2805
2806/* 2,4,6 channel modes */
2807static struct hda_verb alc880_lg_ch2_init[] = {
2808 /* set line-in and mic-in to input */
2809 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2810 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2811 { }
2812};
2813
2814static struct hda_verb alc880_lg_ch4_init[] = {
2815 /* set line-in to out and mic-in to input */
2816 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2817 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2818 { }
2819};
2820
2821static struct hda_verb alc880_lg_ch6_init[] = {
2822 /* set line-in and mic-in to output */
2823 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2824 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2825 { }
2826};
2827
2828static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2829 { 2, alc880_lg_ch2_init },
2830 { 4, alc880_lg_ch4_init },
2831 { 6, alc880_lg_ch6_init },
2832};
2833
2834static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2836 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2837 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2838 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2839 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2840 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2841 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2842 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2845 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2846 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2847 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2848 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2849 {
2850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2851 .name = "Channel Mode",
2852 .info = alc_ch_mode_info,
2853 .get = alc_ch_mode_get,
2854 .put = alc_ch_mode_put,
2855 },
2856 { } /* end */
2857};
2858
2859static struct hda_verb alc880_lg_init_verbs[] = {
2860 /* set capture source to mic-in */
2861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2862 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2864 /* mute all amp mixer inputs */
2865 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2866 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2867 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2868 /* line-in to input */
2869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2871 /* built-in mic */
2872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2874 /* speaker-out */
2875 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2876 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2877 /* mic-in to input */
2878 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2881 /* HP-out */
2882 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2883 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2884 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2885 /* jack sense */
a9fd4f3f 2886 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
2887 { }
2888};
2889
2890/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 2891static void alc880_lg_init_hook(struct hda_codec *codec)
ae6b813a 2892{
a9fd4f3f 2893 struct alc_spec *spec = codec->spec;
ae6b813a 2894
a9fd4f3f
TI
2895 spec->autocfg.hp_pins[0] = 0x1b;
2896 spec->autocfg.speaker_pins[0] = 0x17;
2897 alc_automute_amp(codec);
ae6b813a
TI
2898}
2899
d681518a
TI
2900/*
2901 * LG LW20
2902 *
2903 * Pin assignment:
2904 * Speaker-out: 0x14
2905 * Mic-In: 0x18
e4f41da9
CM
2906 * Built-in Mic-In: 0x19
2907 * Line-In: 0x1b
2908 * HP-Out: 0x1a
d681518a
TI
2909 * SPDIF-Out: 0x1e
2910 */
2911
d681518a 2912static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2913 .num_items = 3,
d681518a
TI
2914 .items = {
2915 { "Mic", 0x0 },
2916 { "Internal Mic", 0x1 },
e4f41da9 2917 { "Line In", 0x2 },
d681518a
TI
2918 },
2919};
2920
0a8c5da3
CM
2921#define alc880_lg_lw_modes alc880_threestack_modes
2922
d681518a 2923static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2924 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2925 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2926 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2927 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2928 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2929 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2930 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2931 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2932 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2933 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2936 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2937 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2938 {
2939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2940 .name = "Channel Mode",
2941 .info = alc_ch_mode_info,
2942 .get = alc_ch_mode_get,
2943 .put = alc_ch_mode_put,
2944 },
d681518a
TI
2945 { } /* end */
2946};
2947
2948static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2949 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2950 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2951 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2952
d681518a
TI
2953 /* set capture source to mic-in */
2954 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2956 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2958 /* speaker-out */
2959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2961 /* HP-out */
d681518a
TI
2962 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2963 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2964 /* mic-in to input */
2965 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2966 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2967 /* built-in mic */
2968 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2969 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2970 /* jack sense */
a9fd4f3f 2971 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
2972 { }
2973};
2974
2975/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 2976static void alc880_lg_lw_init_hook(struct hda_codec *codec)
d681518a 2977{
a9fd4f3f 2978 struct alc_spec *spec = codec->spec;
d681518a 2979
a9fd4f3f
TI
2980 spec->autocfg.hp_pins[0] = 0x1b;
2981 spec->autocfg.speaker_pins[0] = 0x14;
2982 alc_automute_amp(codec);
d681518a
TI
2983}
2984
df99cd33
TI
2985static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2986 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2987 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2990 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2991 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2992 { } /* end */
2993};
2994
2995static struct hda_input_mux alc880_medion_rim_capture_source = {
2996 .num_items = 2,
2997 .items = {
2998 { "Mic", 0x0 },
2999 { "Internal Mic", 0x1 },
3000 },
3001};
3002
3003static struct hda_verb alc880_medion_rim_init_verbs[] = {
3004 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3005
3006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3007 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3008
3009 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3010 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3012 /* Mic2 (as headphone out) for HP output */
3013 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3014 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3015 /* Internal Speaker */
3016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3017 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3018
3019 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3020 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3021
3022 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3023 { }
3024};
3025
3026/* toggle speaker-output according to the hp-jack state */
3027static void alc880_medion_rim_automute(struct hda_codec *codec)
3028{
a9fd4f3f
TI
3029 struct alc_spec *spec = codec->spec;
3030 alc_automute_amp(codec);
3031 /* toggle EAPD */
3032 if (spec->jack_present)
df99cd33
TI
3033 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3034 else
3035 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3036}
3037
3038static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3039 unsigned int res)
3040{
3041 /* Looks like the unsol event is incompatible with the standard
3042 * definition. 4bit tag is placed at 28 bit!
3043 */
3044 if ((res >> 28) == ALC880_HP_EVENT)
3045 alc880_medion_rim_automute(codec);
3046}
3047
a9fd4f3f
TI
3048static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3049{
3050 struct alc_spec *spec = codec->spec;
3051
3052 spec->autocfg.hp_pins[0] = 0x14;
3053 spec->autocfg.speaker_pins[0] = 0x1b;
3054 alc880_medion_rim_automute(codec);
3055}
3056
cb53c626
TI
3057#ifdef CONFIG_SND_HDA_POWER_SAVE
3058static struct hda_amp_list alc880_loopbacks[] = {
3059 { 0x0b, HDA_INPUT, 0 },
3060 { 0x0b, HDA_INPUT, 1 },
3061 { 0x0b, HDA_INPUT, 2 },
3062 { 0x0b, HDA_INPUT, 3 },
3063 { 0x0b, HDA_INPUT, 4 },
3064 { } /* end */
3065};
3066
3067static struct hda_amp_list alc880_lg_loopbacks[] = {
3068 { 0x0b, HDA_INPUT, 1 },
3069 { 0x0b, HDA_INPUT, 6 },
3070 { 0x0b, HDA_INPUT, 7 },
3071 { } /* end */
3072};
3073#endif
3074
ae6b813a
TI
3075/*
3076 * Common callbacks
e9edcee0
TI
3077 */
3078
1da177e4
LT
3079static int alc_init(struct hda_codec *codec)
3080{
3081 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3082 unsigned int i;
3083
2c3bf9ab 3084 alc_fix_pll(codec);
4a79ba34 3085 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3086
e9edcee0
TI
3087 for (i = 0; i < spec->num_init_verbs; i++)
3088 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3089
3090 if (spec->init_hook)
3091 spec->init_hook(codec);
3092
1da177e4
LT
3093 return 0;
3094}
3095
ae6b813a
TI
3096static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3097{
3098 struct alc_spec *spec = codec->spec;
3099
3100 if (spec->unsol_event)
3101 spec->unsol_event(codec, res);
3102}
3103
cb53c626
TI
3104#ifdef CONFIG_SND_HDA_POWER_SAVE
3105static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3106{
3107 struct alc_spec *spec = codec->spec;
3108 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3109}
3110#endif
3111
1da177e4
LT
3112/*
3113 * Analog playback callbacks
3114 */
3115static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3116 struct hda_codec *codec,
c8b6bf9b 3117 struct snd_pcm_substream *substream)
1da177e4
LT
3118{
3119 struct alc_spec *spec = codec->spec;
9a08160b
TI
3120 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3121 hinfo);
1da177e4
LT
3122}
3123
3124static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3125 struct hda_codec *codec,
3126 unsigned int stream_tag,
3127 unsigned int format,
c8b6bf9b 3128 struct snd_pcm_substream *substream)
1da177e4
LT
3129{
3130 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3131 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3132 stream_tag, format, substream);
1da177e4
LT
3133}
3134
3135static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3136 struct hda_codec *codec,
c8b6bf9b 3137 struct snd_pcm_substream *substream)
1da177e4
LT
3138{
3139 struct alc_spec *spec = codec->spec;
3140 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3141}
3142
3143/*
3144 * Digital out
3145 */
3146static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3147 struct hda_codec *codec,
c8b6bf9b 3148 struct snd_pcm_substream *substream)
1da177e4
LT
3149{
3150 struct alc_spec *spec = codec->spec;
3151 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3152}
3153
6b97eb45
TI
3154static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3155 struct hda_codec *codec,
3156 unsigned int stream_tag,
3157 unsigned int format,
3158 struct snd_pcm_substream *substream)
3159{
3160 struct alc_spec *spec = codec->spec;
3161 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3162 stream_tag, format, substream);
3163}
3164
9b5f12e5
TI
3165static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3166 struct hda_codec *codec,
3167 struct snd_pcm_substream *substream)
3168{
3169 struct alc_spec *spec = codec->spec;
3170 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3171}
3172
1da177e4
LT
3173static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3174 struct hda_codec *codec,
c8b6bf9b 3175 struct snd_pcm_substream *substream)
1da177e4
LT
3176{
3177 struct alc_spec *spec = codec->spec;
3178 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3179}
3180
3181/*
3182 * Analog capture
3183 */
6330079f 3184static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3185 struct hda_codec *codec,
3186 unsigned int stream_tag,
3187 unsigned int format,
c8b6bf9b 3188 struct snd_pcm_substream *substream)
1da177e4
LT
3189{
3190 struct alc_spec *spec = codec->spec;
3191
6330079f 3192 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3193 stream_tag, 0, format);
3194 return 0;
3195}
3196
6330079f 3197static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3198 struct hda_codec *codec,
c8b6bf9b 3199 struct snd_pcm_substream *substream)
1da177e4
LT
3200{
3201 struct alc_spec *spec = codec->spec;
3202
888afa15
TI
3203 snd_hda_codec_cleanup_stream(codec,
3204 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3205 return 0;
3206}
3207
3208
3209/*
3210 */
3211static struct hda_pcm_stream alc880_pcm_analog_playback = {
3212 .substreams = 1,
3213 .channels_min = 2,
3214 .channels_max = 8,
e9edcee0 3215 /* NID is set in alc_build_pcms */
1da177e4
LT
3216 .ops = {
3217 .open = alc880_playback_pcm_open,
3218 .prepare = alc880_playback_pcm_prepare,
3219 .cleanup = alc880_playback_pcm_cleanup
3220 },
3221};
3222
3223static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3224 .substreams = 1,
3225 .channels_min = 2,
3226 .channels_max = 2,
3227 /* NID is set in alc_build_pcms */
3228};
3229
3230static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3231 .substreams = 1,
3232 .channels_min = 2,
3233 .channels_max = 2,
3234 /* NID is set in alc_build_pcms */
3235};
3236
3237static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3238 .substreams = 2, /* can be overridden */
1da177e4
LT
3239 .channels_min = 2,
3240 .channels_max = 2,
e9edcee0 3241 /* NID is set in alc_build_pcms */
1da177e4 3242 .ops = {
6330079f
TI
3243 .prepare = alc880_alt_capture_pcm_prepare,
3244 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3245 },
3246};
3247
3248static struct hda_pcm_stream alc880_pcm_digital_playback = {
3249 .substreams = 1,
3250 .channels_min = 2,
3251 .channels_max = 2,
3252 /* NID is set in alc_build_pcms */
3253 .ops = {
3254 .open = alc880_dig_playback_pcm_open,
6b97eb45 3255 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3256 .prepare = alc880_dig_playback_pcm_prepare,
3257 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3258 },
3259};
3260
3261static struct hda_pcm_stream alc880_pcm_digital_capture = {
3262 .substreams = 1,
3263 .channels_min = 2,
3264 .channels_max = 2,
3265 /* NID is set in alc_build_pcms */
3266};
3267
4c5186ed 3268/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3269static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3270 .substreams = 0,
3271 .channels_min = 0,
3272 .channels_max = 0,
3273};
3274
1da177e4
LT
3275static int alc_build_pcms(struct hda_codec *codec)
3276{
3277 struct alc_spec *spec = codec->spec;
3278 struct hda_pcm *info = spec->pcm_rec;
3279 int i;
3280
3281 codec->num_pcms = 1;
3282 codec->pcm_info = info;
3283
e64f14f4
TI
3284 if (spec->no_analog)
3285 goto skip_analog;
3286
812a2cca
TI
3287 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3288 "%s Analog", codec->chip_name);
1da177e4 3289 info->name = spec->stream_name_analog;
812a2cca 3290
4a471b7d 3291 if (spec->stream_analog_playback) {
da3cec35
TI
3292 if (snd_BUG_ON(!spec->multiout.dac_nids))
3293 return -EINVAL;
4a471b7d
TI
3294 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3295 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3296 }
3297 if (spec->stream_analog_capture) {
da3cec35
TI
3298 if (snd_BUG_ON(!spec->adc_nids))
3299 return -EINVAL;
4a471b7d
TI
3300 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3301 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3302 }
3303
3304 if (spec->channel_mode) {
3305 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3306 for (i = 0; i < spec->num_channel_mode; i++) {
3307 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3308 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3309 }
1da177e4
LT
3310 }
3311 }
3312
e64f14f4 3313 skip_analog:
e08a007d 3314 /* SPDIF for stream index #1 */
1da177e4 3315 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3316 snprintf(spec->stream_name_digital,
3317 sizeof(spec->stream_name_digital),
3318 "%s Digital", codec->chip_name);
e08a007d 3319 codec->num_pcms = 2;
b25c9da1 3320 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3321 info = spec->pcm_rec + 1;
1da177e4 3322 info->name = spec->stream_name_digital;
8c441982
TI
3323 if (spec->dig_out_type)
3324 info->pcm_type = spec->dig_out_type;
3325 else
3326 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3327 if (spec->multiout.dig_out_nid &&
3328 spec->stream_digital_playback) {
1da177e4
LT
3329 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3330 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3331 }
4a471b7d
TI
3332 if (spec->dig_in_nid &&
3333 spec->stream_digital_capture) {
1da177e4
LT
3334 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3335 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3336 }
963f803f
TI
3337 /* FIXME: do we need this for all Realtek codec models? */
3338 codec->spdif_status_reset = 1;
1da177e4
LT
3339 }
3340
e64f14f4
TI
3341 if (spec->no_analog)
3342 return 0;
3343
e08a007d
TI
3344 /* If the use of more than one ADC is requested for the current
3345 * model, configure a second analog capture-only PCM.
3346 */
3347 /* Additional Analaog capture for index #2 */
6330079f
TI
3348 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3349 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3350 codec->num_pcms = 3;
c06134d7 3351 info = spec->pcm_rec + 2;
e08a007d 3352 info->name = spec->stream_name_analog;
6330079f
TI
3353 if (spec->alt_dac_nid) {
3354 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3355 *spec->stream_analog_alt_playback;
3356 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3357 spec->alt_dac_nid;
3358 } else {
3359 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3360 alc_pcm_null_stream;
3361 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3362 }
3363 if (spec->num_adc_nids > 1) {
3364 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3365 *spec->stream_analog_alt_capture;
3366 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3367 spec->adc_nids[1];
3368 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3369 spec->num_adc_nids - 1;
3370 } else {
3371 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3372 alc_pcm_null_stream;
3373 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3374 }
3375 }
3376
1da177e4
LT
3377 return 0;
3378}
3379
603c4019
TI
3380static void alc_free_kctls(struct hda_codec *codec)
3381{
3382 struct alc_spec *spec = codec->spec;
3383
3384 if (spec->kctls.list) {
3385 struct snd_kcontrol_new *kctl = spec->kctls.list;
3386 int i;
3387 for (i = 0; i < spec->kctls.used; i++)
3388 kfree(kctl[i].name);
3389 }
3390 snd_array_free(&spec->kctls);
3391}
3392
1da177e4
LT
3393static void alc_free(struct hda_codec *codec)
3394{
e9edcee0 3395 struct alc_spec *spec = codec->spec;
e9edcee0 3396
f12ab1e0 3397 if (!spec)
e9edcee0
TI
3398 return;
3399
603c4019 3400 alc_free_kctls(codec);
e9edcee0 3401 kfree(spec);
680cd536 3402 snd_hda_detach_beep_device(codec);
1da177e4
LT
3403}
3404
e044c39a 3405#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3406static int alc_resume(struct hda_codec *codec)
3407{
e044c39a
TI
3408 codec->patch_ops.init(codec);
3409 snd_hda_codec_resume_amp(codec);
3410 snd_hda_codec_resume_cache(codec);
3411 return 0;
3412}
e044c39a
TI
3413#endif
3414
1da177e4
LT
3415/*
3416 */
3417static struct hda_codec_ops alc_patch_ops = {
3418 .build_controls = alc_build_controls,
3419 .build_pcms = alc_build_pcms,
3420 .init = alc_init,
3421 .free = alc_free,
ae6b813a 3422 .unsol_event = alc_unsol_event,
e044c39a
TI
3423#ifdef SND_HDA_NEEDS_RESUME
3424 .resume = alc_resume,
3425#endif
cb53c626
TI
3426#ifdef CONFIG_SND_HDA_POWER_SAVE
3427 .check_power_status = alc_check_power_status,
3428#endif
1da177e4
LT
3429};
3430
2fa522be
TI
3431
3432/*
3433 * Test configuration for debugging
3434 *
3435 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3436 * enum controls.
3437 */
3438#ifdef CONFIG_SND_DEBUG
3439static hda_nid_t alc880_test_dac_nids[4] = {
3440 0x02, 0x03, 0x04, 0x05
3441};
3442
3443static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3444 .num_items = 7,
2fa522be
TI
3445 .items = {
3446 { "In-1", 0x0 },
3447 { "In-2", 0x1 },
3448 { "In-3", 0x2 },
3449 { "In-4", 0x3 },
3450 { "CD", 0x4 },
ae6b813a
TI
3451 { "Front", 0x5 },
3452 { "Surround", 0x6 },
2fa522be
TI
3453 },
3454};
3455
d2a6d7dc 3456static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3457 { 2, NULL },
fd2c326d 3458 { 4, NULL },
2fa522be 3459 { 6, NULL },
fd2c326d 3460 { 8, NULL },
2fa522be
TI
3461};
3462
9c7f852e
TI
3463static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3464 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3465{
3466 static char *texts[] = {
3467 "N/A", "Line Out", "HP Out",
3468 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3469 };
3470 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3471 uinfo->count = 1;
3472 uinfo->value.enumerated.items = 8;
3473 if (uinfo->value.enumerated.item >= 8)
3474 uinfo->value.enumerated.item = 7;
3475 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3476 return 0;
3477}
3478
9c7f852e
TI
3479static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3480 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3481{
3482 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3483 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3484 unsigned int pin_ctl, item = 0;
3485
3486 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3487 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3488 if (pin_ctl & AC_PINCTL_OUT_EN) {
3489 if (pin_ctl & AC_PINCTL_HP_EN)
3490 item = 2;
3491 else
3492 item = 1;
3493 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3494 switch (pin_ctl & AC_PINCTL_VREFEN) {
3495 case AC_PINCTL_VREF_HIZ: item = 3; break;
3496 case AC_PINCTL_VREF_50: item = 4; break;
3497 case AC_PINCTL_VREF_GRD: item = 5; break;
3498 case AC_PINCTL_VREF_80: item = 6; break;
3499 case AC_PINCTL_VREF_100: item = 7; break;
3500 }
3501 }
3502 ucontrol->value.enumerated.item[0] = item;
3503 return 0;
3504}
3505
9c7f852e
TI
3506static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3507 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3508{
3509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3510 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3511 static unsigned int ctls[] = {
3512 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3513 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3514 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3515 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3516 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3517 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3518 };
3519 unsigned int old_ctl, new_ctl;
3520
3521 old_ctl = snd_hda_codec_read(codec, nid, 0,
3522 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3523 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3524 if (old_ctl != new_ctl) {
82beb8fd
TI
3525 int val;
3526 snd_hda_codec_write_cache(codec, nid, 0,
3527 AC_VERB_SET_PIN_WIDGET_CONTROL,
3528 new_ctl);
47fd830a
TI
3529 val = ucontrol->value.enumerated.item[0] >= 3 ?
3530 HDA_AMP_MUTE : 0;
3531 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3532 HDA_AMP_MUTE, val);
2fa522be
TI
3533 return 1;
3534 }
3535 return 0;
3536}
3537
9c7f852e
TI
3538static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3539 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3540{
3541 static char *texts[] = {
3542 "Front", "Surround", "CLFE", "Side"
3543 };
3544 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3545 uinfo->count = 1;
3546 uinfo->value.enumerated.items = 4;
3547 if (uinfo->value.enumerated.item >= 4)
3548 uinfo->value.enumerated.item = 3;
3549 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3550 return 0;
3551}
3552
9c7f852e
TI
3553static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3554 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3555{
3556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3557 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3558 unsigned int sel;
3559
3560 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3561 ucontrol->value.enumerated.item[0] = sel & 3;
3562 return 0;
3563}
3564
9c7f852e
TI
3565static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3566 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3567{
3568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3569 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3570 unsigned int sel;
3571
3572 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3573 if (ucontrol->value.enumerated.item[0] != sel) {
3574 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3575 snd_hda_codec_write_cache(codec, nid, 0,
3576 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3577 return 1;
3578 }
3579 return 0;
3580}
3581
3582#define PIN_CTL_TEST(xname,nid) { \
3583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3584 .name = xname, \
3585 .info = alc_test_pin_ctl_info, \
3586 .get = alc_test_pin_ctl_get, \
3587 .put = alc_test_pin_ctl_put, \
3588 .private_value = nid \
3589 }
3590
3591#define PIN_SRC_TEST(xname,nid) { \
3592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3593 .name = xname, \
3594 .info = alc_test_pin_src_info, \
3595 .get = alc_test_pin_src_get, \
3596 .put = alc_test_pin_src_put, \
3597 .private_value = nid \
3598 }
3599
c8b6bf9b 3600static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3601 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3602 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3603 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3604 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3605 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3606 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3607 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3608 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3609 PIN_CTL_TEST("Front Pin Mode", 0x14),
3610 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3611 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3612 PIN_CTL_TEST("Side Pin Mode", 0x17),
3613 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3614 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3615 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3616 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3617 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3618 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3619 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3620 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3621 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3622 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3623 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3624 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3625 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3626 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3627 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3628 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3629 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3630 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3631 {
3632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3633 .name = "Channel Mode",
df694daa
KY
3634 .info = alc_ch_mode_info,
3635 .get = alc_ch_mode_get,
3636 .put = alc_ch_mode_put,
2fa522be
TI
3637 },
3638 { } /* end */
3639};
3640
3641static struct hda_verb alc880_test_init_verbs[] = {
3642 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3643 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3644 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3647 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3648 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3649 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3650 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3651 /* Vol output for 0x0c-0x0f */
05acb863
TI
3652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3653 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3654 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3656 /* Set output pins 0x14-0x17 */
05acb863
TI
3657 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3659 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3661 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3662 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3665 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3666 /* Set input pins 0x18-0x1c */
16ded525
TI
3667 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3668 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3669 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3670 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3671 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3672 /* Mute input pins 0x18-0x1b */
05acb863
TI
3673 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3674 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3676 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3677 /* ADC set up */
05acb863 3678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3679 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3680 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3681 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3682 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3683 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3684 /* Analog input/passthru */
3685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3690 { }
3691};
3692#endif
3693
1da177e4
LT
3694/*
3695 */
3696
f5fcc13c
TI
3697static const char *alc880_models[ALC880_MODEL_LAST] = {
3698 [ALC880_3ST] = "3stack",
3699 [ALC880_TCL_S700] = "tcl",
3700 [ALC880_3ST_DIG] = "3stack-digout",
3701 [ALC880_CLEVO] = "clevo",
3702 [ALC880_5ST] = "5stack",
3703 [ALC880_5ST_DIG] = "5stack-digout",
3704 [ALC880_W810] = "w810",
3705 [ALC880_Z71V] = "z71v",
3706 [ALC880_6ST] = "6stack",
3707 [ALC880_6ST_DIG] = "6stack-digout",
3708 [ALC880_ASUS] = "asus",
3709 [ALC880_ASUS_W1V] = "asus-w1v",
3710 [ALC880_ASUS_DIG] = "asus-dig",
3711 [ALC880_ASUS_DIG2] = "asus-dig2",
3712 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3713 [ALC880_UNIWILL_P53] = "uniwill-p53",
3714 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3715 [ALC880_F1734] = "F1734",
3716 [ALC880_LG] = "lg",
3717 [ALC880_LG_LW] = "lg-lw",
df99cd33 3718 [ALC880_MEDION_RIM] = "medion",
2fa522be 3719#ifdef CONFIG_SND_DEBUG
f5fcc13c 3720 [ALC880_TEST] = "test",
2fa522be 3721#endif
f5fcc13c
TI
3722 [ALC880_AUTO] = "auto",
3723};
3724
3725static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3726 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3727 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3728 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3729 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3730 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3731 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3732 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3733 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3734 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3735 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3736 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3737 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3738 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3739 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3740 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3741 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3742 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3743 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3744 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3745 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3746 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3747 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3748 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3749 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3750 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 3751 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3752 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3753 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3754 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3755 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3756 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3757 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3758 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3759 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3760 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3761 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3762 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3763 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3764 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3765 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3766 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3767 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3768 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3769 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3770 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3771 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3772 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3773 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3774 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3775 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3776 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3777 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3778 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3779 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3780 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3781 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3782 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3783 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3784 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3785 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3786 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3787 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3788 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3789 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3790 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3791 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3792 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3793 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
3794 /* default Intel */
3795 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
3796 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3797 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3798 {}
3799};
3800
16ded525 3801/*
df694daa 3802 * ALC880 codec presets
16ded525 3803 */
16ded525
TI
3804static struct alc_config_preset alc880_presets[] = {
3805 [ALC880_3ST] = {
e9edcee0 3806 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3807 .init_verbs = { alc880_volume_init_verbs,
3808 alc880_pin_3stack_init_verbs },
16ded525 3809 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3810 .dac_nids = alc880_dac_nids,
16ded525
TI
3811 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3812 .channel_mode = alc880_threestack_modes,
4e195a7b 3813 .need_dac_fix = 1,
16ded525
TI
3814 .input_mux = &alc880_capture_source,
3815 },
3816 [ALC880_3ST_DIG] = {
e9edcee0 3817 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3818 .init_verbs = { alc880_volume_init_verbs,
3819 alc880_pin_3stack_init_verbs },
16ded525 3820 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3821 .dac_nids = alc880_dac_nids,
3822 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3823 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3824 .channel_mode = alc880_threestack_modes,
4e195a7b 3825 .need_dac_fix = 1,
16ded525
TI
3826 .input_mux = &alc880_capture_source,
3827 },
df694daa
KY
3828 [ALC880_TCL_S700] = {
3829 .mixers = { alc880_tcl_s700_mixer },
3830 .init_verbs = { alc880_volume_init_verbs,
3831 alc880_pin_tcl_S700_init_verbs,
3832 alc880_gpio2_init_verbs },
3833 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3834 .dac_nids = alc880_dac_nids,
f9e336f6
TI
3835 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3836 .num_adc_nids = 1, /* single ADC */
df694daa
KY
3837 .hp_nid = 0x03,
3838 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3839 .channel_mode = alc880_2_jack_modes,
3840 .input_mux = &alc880_capture_source,
3841 },
16ded525 3842 [ALC880_5ST] = {
f12ab1e0
TI
3843 .mixers = { alc880_three_stack_mixer,
3844 alc880_five_stack_mixer},
3845 .init_verbs = { alc880_volume_init_verbs,
3846 alc880_pin_5stack_init_verbs },
16ded525
TI
3847 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3848 .dac_nids = alc880_dac_nids,
16ded525
TI
3849 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3850 .channel_mode = alc880_fivestack_modes,
3851 .input_mux = &alc880_capture_source,
3852 },
3853 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3854 .mixers = { alc880_three_stack_mixer,
3855 alc880_five_stack_mixer },
3856 .init_verbs = { alc880_volume_init_verbs,
3857 alc880_pin_5stack_init_verbs },
16ded525
TI
3858 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3859 .dac_nids = alc880_dac_nids,
3860 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3861 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3862 .channel_mode = alc880_fivestack_modes,
3863 .input_mux = &alc880_capture_source,
3864 },
b6482d48
TI
3865 [ALC880_6ST] = {
3866 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3867 .init_verbs = { alc880_volume_init_verbs,
3868 alc880_pin_6stack_init_verbs },
b6482d48
TI
3869 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3870 .dac_nids = alc880_6st_dac_nids,
3871 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3872 .channel_mode = alc880_sixstack_modes,
3873 .input_mux = &alc880_6stack_capture_source,
3874 },
16ded525 3875 [ALC880_6ST_DIG] = {
e9edcee0 3876 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3877 .init_verbs = { alc880_volume_init_verbs,
3878 alc880_pin_6stack_init_verbs },
16ded525
TI
3879 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3880 .dac_nids = alc880_6st_dac_nids,
3881 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3882 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3883 .channel_mode = alc880_sixstack_modes,
3884 .input_mux = &alc880_6stack_capture_source,
3885 },
3886 [ALC880_W810] = {
e9edcee0 3887 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3888 .init_verbs = { alc880_volume_init_verbs,
3889 alc880_pin_w810_init_verbs,
b0af0de5 3890 alc880_gpio2_init_verbs },
16ded525
TI
3891 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3892 .dac_nids = alc880_w810_dac_nids,
3893 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3894 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3895 .channel_mode = alc880_w810_modes,
3896 .input_mux = &alc880_capture_source,
3897 },
3898 [ALC880_Z71V] = {
e9edcee0 3899 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3900 .init_verbs = { alc880_volume_init_verbs,
3901 alc880_pin_z71v_init_verbs },
16ded525
TI
3902 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3903 .dac_nids = alc880_z71v_dac_nids,
3904 .dig_out_nid = ALC880_DIGOUT_NID,
3905 .hp_nid = 0x03,
e9edcee0
TI
3906 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3907 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3908 .input_mux = &alc880_capture_source,
3909 },
3910 [ALC880_F1734] = {
e9edcee0 3911 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3912 .init_verbs = { alc880_volume_init_verbs,
3913 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3914 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3915 .dac_nids = alc880_f1734_dac_nids,
3916 .hp_nid = 0x02,
3917 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3918 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3919 .input_mux = &alc880_f1734_capture_source,
3920 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 3921 .init_hook = alc880_uniwill_p53_init_hook,
16ded525
TI
3922 },
3923 [ALC880_ASUS] = {
e9edcee0 3924 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3925 .init_verbs = { alc880_volume_init_verbs,
3926 alc880_pin_asus_init_verbs,
e9edcee0
TI
3927 alc880_gpio1_init_verbs },
3928 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3929 .dac_nids = alc880_asus_dac_nids,
3930 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3931 .channel_mode = alc880_asus_modes,
4e195a7b 3932 .need_dac_fix = 1,
16ded525
TI
3933 .input_mux = &alc880_capture_source,
3934 },
3935 [ALC880_ASUS_DIG] = {
e9edcee0 3936 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3937 .init_verbs = { alc880_volume_init_verbs,
3938 alc880_pin_asus_init_verbs,
e9edcee0
TI
3939 alc880_gpio1_init_verbs },
3940 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3941 .dac_nids = alc880_asus_dac_nids,
16ded525 3942 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3943 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3944 .channel_mode = alc880_asus_modes,
4e195a7b 3945 .need_dac_fix = 1,
16ded525
TI
3946 .input_mux = &alc880_capture_source,
3947 },
df694daa
KY
3948 [ALC880_ASUS_DIG2] = {
3949 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3950 .init_verbs = { alc880_volume_init_verbs,
3951 alc880_pin_asus_init_verbs,
df694daa
KY
3952 alc880_gpio2_init_verbs }, /* use GPIO2 */
3953 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3954 .dac_nids = alc880_asus_dac_nids,
3955 .dig_out_nid = ALC880_DIGOUT_NID,
3956 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3957 .channel_mode = alc880_asus_modes,
4e195a7b 3958 .need_dac_fix = 1,
df694daa
KY
3959 .input_mux = &alc880_capture_source,
3960 },
16ded525 3961 [ALC880_ASUS_W1V] = {
e9edcee0 3962 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3963 .init_verbs = { alc880_volume_init_verbs,
3964 alc880_pin_asus_init_verbs,
e9edcee0
TI
3965 alc880_gpio1_init_verbs },
3966 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3967 .dac_nids = alc880_asus_dac_nids,
16ded525 3968 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3969 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3970 .channel_mode = alc880_asus_modes,
4e195a7b 3971 .need_dac_fix = 1,
16ded525
TI
3972 .input_mux = &alc880_capture_source,
3973 },
3974 [ALC880_UNIWILL_DIG] = {
45bdd1c1 3975 .mixers = { alc880_asus_mixer },
ccc656ce
KY
3976 .init_verbs = { alc880_volume_init_verbs,
3977 alc880_pin_asus_init_verbs },
e9edcee0
TI
3978 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3979 .dac_nids = alc880_asus_dac_nids,
16ded525 3980 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3981 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3982 .channel_mode = alc880_asus_modes,
4e195a7b 3983 .need_dac_fix = 1,
16ded525
TI
3984 .input_mux = &alc880_capture_source,
3985 },
ccc656ce
KY
3986 [ALC880_UNIWILL] = {
3987 .mixers = { alc880_uniwill_mixer },
3988 .init_verbs = { alc880_volume_init_verbs,
3989 alc880_uniwill_init_verbs },
3990 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3991 .dac_nids = alc880_asus_dac_nids,
3992 .dig_out_nid = ALC880_DIGOUT_NID,
3993 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3994 .channel_mode = alc880_threestack_modes,
3995 .need_dac_fix = 1,
3996 .input_mux = &alc880_capture_source,
3997 .unsol_event = alc880_uniwill_unsol_event,
a9fd4f3f 3998 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
3999 },
4000 [ALC880_UNIWILL_P53] = {
4001 .mixers = { alc880_uniwill_p53_mixer },
4002 .init_verbs = { alc880_volume_init_verbs,
4003 alc880_uniwill_p53_init_verbs },
4004 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4005 .dac_nids = alc880_asus_dac_nids,
4006 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4007 .channel_mode = alc880_threestack_modes,
4008 .input_mux = &alc880_capture_source,
4009 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 4010 .init_hook = alc880_uniwill_p53_init_hook,
2cf9f0fc
TD
4011 },
4012 [ALC880_FUJITSU] = {
45bdd1c1 4013 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4014 .init_verbs = { alc880_volume_init_verbs,
4015 alc880_uniwill_p53_init_verbs,
4016 alc880_beep_init_verbs },
4017 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4018 .dac_nids = alc880_dac_nids,
d53d7d9e 4019 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4020 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4021 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4022 .input_mux = &alc880_capture_source,
4023 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 4024 .init_hook = alc880_uniwill_p53_init_hook,
ccc656ce 4025 },
df694daa
KY
4026 [ALC880_CLEVO] = {
4027 .mixers = { alc880_three_stack_mixer },
4028 .init_verbs = { alc880_volume_init_verbs,
4029 alc880_pin_clevo_init_verbs },
4030 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4031 .dac_nids = alc880_dac_nids,
4032 .hp_nid = 0x03,
4033 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4034 .channel_mode = alc880_threestack_modes,
4e195a7b 4035 .need_dac_fix = 1,
df694daa
KY
4036 .input_mux = &alc880_capture_source,
4037 },
ae6b813a
TI
4038 [ALC880_LG] = {
4039 .mixers = { alc880_lg_mixer },
4040 .init_verbs = { alc880_volume_init_verbs,
4041 alc880_lg_init_verbs },
4042 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4043 .dac_nids = alc880_lg_dac_nids,
4044 .dig_out_nid = ALC880_DIGOUT_NID,
4045 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4046 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4047 .need_dac_fix = 1,
ae6b813a 4048 .input_mux = &alc880_lg_capture_source,
a9fd4f3f
TI
4049 .unsol_event = alc_automute_amp_unsol_event,
4050 .init_hook = alc880_lg_init_hook,
cb53c626
TI
4051#ifdef CONFIG_SND_HDA_POWER_SAVE
4052 .loopbacks = alc880_lg_loopbacks,
4053#endif
ae6b813a 4054 },
d681518a
TI
4055 [ALC880_LG_LW] = {
4056 .mixers = { alc880_lg_lw_mixer },
4057 .init_verbs = { alc880_volume_init_verbs,
4058 alc880_lg_lw_init_verbs },
0a8c5da3 4059 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4060 .dac_nids = alc880_dac_nids,
4061 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4062 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4063 .channel_mode = alc880_lg_lw_modes,
d681518a 4064 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f
TI
4065 .unsol_event = alc_automute_amp_unsol_event,
4066 .init_hook = alc880_lg_lw_init_hook,
d681518a 4067 },
df99cd33
TI
4068 [ALC880_MEDION_RIM] = {
4069 .mixers = { alc880_medion_rim_mixer },
4070 .init_verbs = { alc880_volume_init_verbs,
4071 alc880_medion_rim_init_verbs,
4072 alc_gpio2_init_verbs },
4073 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4074 .dac_nids = alc880_dac_nids,
4075 .dig_out_nid = ALC880_DIGOUT_NID,
4076 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4077 .channel_mode = alc880_2_jack_modes,
4078 .input_mux = &alc880_medion_rim_capture_source,
4079 .unsol_event = alc880_medion_rim_unsol_event,
a9fd4f3f 4080 .init_hook = alc880_medion_rim_init_hook,
df99cd33 4081 },
16ded525
TI
4082#ifdef CONFIG_SND_DEBUG
4083 [ALC880_TEST] = {
e9edcee0
TI
4084 .mixers = { alc880_test_mixer },
4085 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4086 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4087 .dac_nids = alc880_test_dac_nids,
4088 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4089 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4090 .channel_mode = alc880_test_modes,
4091 .input_mux = &alc880_test_capture_source,
4092 },
4093#endif
4094};
4095
e9edcee0
TI
4096/*
4097 * Automatic parse of I/O pins from the BIOS configuration
4098 */
4099
e9edcee0
TI
4100enum {
4101 ALC_CTL_WIDGET_VOL,
4102 ALC_CTL_WIDGET_MUTE,
4103 ALC_CTL_BIND_MUTE,
4104};
c8b6bf9b 4105static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4106 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4107 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4108 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4109};
4110
4111/* add dynamic controls */
f12ab1e0
TI
4112static int add_control(struct alc_spec *spec, int type, const char *name,
4113 unsigned long val)
e9edcee0 4114{
c8b6bf9b 4115 struct snd_kcontrol_new *knew;
e9edcee0 4116
603c4019
TI
4117 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4118 knew = snd_array_new(&spec->kctls);
4119 if (!knew)
4120 return -ENOMEM;
e9edcee0 4121 *knew = alc880_control_templates[type];
543537bd 4122 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4123 if (!knew->name)
e9edcee0
TI
4124 return -ENOMEM;
4125 knew->private_value = val;
e9edcee0
TI
4126 return 0;
4127}
4128
4129#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4130#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4131#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4132#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4133#define alc880_is_input_pin(nid) ((nid) >= 0x18)
4134#define alc880_input_pin_idx(nid) ((nid) - 0x18)
4135#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4136#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4137#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4138#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4139#define ALC880_PIN_CD_NID 0x1c
4140
4141/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4142static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4143 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4144{
4145 hda_nid_t nid;
4146 int assigned[4];
4147 int i, j;
4148
4149 memset(assigned, 0, sizeof(assigned));
b0af0de5 4150 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4151
4152 /* check the pins hardwired to audio widget */
4153 for (i = 0; i < cfg->line_outs; i++) {
4154 nid = cfg->line_out_pins[i];
4155 if (alc880_is_fixed_pin(nid)) {
4156 int idx = alc880_fixed_pin_idx(nid);
5014f193 4157 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4158 assigned[idx] = 1;
4159 }
4160 }
4161 /* left pins can be connect to any audio widget */
4162 for (i = 0; i < cfg->line_outs; i++) {
4163 nid = cfg->line_out_pins[i];
4164 if (alc880_is_fixed_pin(nid))
4165 continue;
4166 /* search for an empty channel */
4167 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4168 if (!assigned[j]) {
4169 spec->multiout.dac_nids[i] =
4170 alc880_idx_to_dac(j);
e9edcee0
TI
4171 assigned[j] = 1;
4172 break;
4173 }
4174 }
4175 }
4176 spec->multiout.num_dacs = cfg->line_outs;
4177 return 0;
4178}
4179
4180/* add playback controls from the parsed DAC table */
df694daa
KY
4181static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4182 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4183{
4184 char name[32];
f12ab1e0
TI
4185 static const char *chname[4] = {
4186 "Front", "Surround", NULL /*CLFE*/, "Side"
4187 };
e9edcee0
TI
4188 hda_nid_t nid;
4189 int i, err;
4190
4191 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4192 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4193 continue;
4194 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4195 if (i == 2) {
4196 /* Center/LFE */
f12ab1e0
TI
4197 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4198 "Center Playback Volume",
4199 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4200 HDA_OUTPUT));
4201 if (err < 0)
e9edcee0 4202 return err;
f12ab1e0
TI
4203 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4204 "LFE Playback Volume",
4205 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4206 HDA_OUTPUT));
4207 if (err < 0)
e9edcee0 4208 return err;
f12ab1e0
TI
4209 err = add_control(spec, ALC_CTL_BIND_MUTE,
4210 "Center Playback Switch",
4211 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4212 HDA_INPUT));
4213 if (err < 0)
e9edcee0 4214 return err;
f12ab1e0
TI
4215 err = add_control(spec, ALC_CTL_BIND_MUTE,
4216 "LFE Playback Switch",
4217 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4218 HDA_INPUT));
4219 if (err < 0)
e9edcee0
TI
4220 return err;
4221 } else {
4222 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
4223 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4224 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4225 HDA_OUTPUT));
4226 if (err < 0)
e9edcee0
TI
4227 return err;
4228 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
4229 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4230 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4231 HDA_INPUT));
4232 if (err < 0)
e9edcee0
TI
4233 return err;
4234 }
4235 }
e9edcee0
TI
4236 return 0;
4237}
4238
8d88bc3d
TI
4239/* add playback controls for speaker and HP outputs */
4240static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4241 const char *pfx)
e9edcee0
TI
4242{
4243 hda_nid_t nid;
4244 int err;
8d88bc3d 4245 char name[32];
e9edcee0 4246
f12ab1e0 4247 if (!pin)
e9edcee0
TI
4248 return 0;
4249
4250 if (alc880_is_fixed_pin(pin)) {
4251 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4252 /* specify the DAC as the extra output */
f12ab1e0 4253 if (!spec->multiout.hp_nid)
e9edcee0 4254 spec->multiout.hp_nid = nid;
82bc955f
TI
4255 else
4256 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4257 /* control HP volume/switch on the output mixer amp */
4258 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 4259 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4260 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4261 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4262 if (err < 0)
e9edcee0 4263 return err;
8d88bc3d 4264 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4265 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4266 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4267 if (err < 0)
e9edcee0
TI
4268 return err;
4269 } else if (alc880_is_multi_pin(pin)) {
4270 /* set manual connection */
e9edcee0 4271 /* we have only a switch on HP-out PIN */
8d88bc3d 4272 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4273 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4274 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4275 if (err < 0)
e9edcee0
TI
4276 return err;
4277 }
4278 return 0;
4279}
4280
4281/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4282static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4283 const char *ctlname,
df694daa 4284 int idx, hda_nid_t mix_nid)
e9edcee0
TI
4285{
4286 char name[32];
df694daa 4287 int err;
e9edcee0
TI
4288
4289 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
4290 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4291 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4292 if (err < 0)
e9edcee0
TI
4293 return err;
4294 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
4295 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4296 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4297 if (err < 0)
e9edcee0
TI
4298 return err;
4299 return 0;
4300}
4301
4302/* create playback/capture controls for input pins */
df694daa
KY
4303static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4304 const struct auto_pin_cfg *cfg)
e9edcee0 4305{
61b9b9b1 4306 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4307 int i, err, idx;
e9edcee0
TI
4308
4309 for (i = 0; i < AUTO_PIN_LAST; i++) {
4310 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 4311 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
4312 err = new_analog_input(spec, cfg->input_pins[i],
4313 auto_pin_cfg_labels[i],
df694daa 4314 idx, 0x0b);
e9edcee0
TI
4315 if (err < 0)
4316 return err;
f12ab1e0
TI
4317 imux->items[imux->num_items].label =
4318 auto_pin_cfg_labels[i];
4319 imux->items[imux->num_items].index =
4320 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
4321 imux->num_items++;
4322 }
4323 }
4324 return 0;
4325}
4326
f6c7e546
TI
4327static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4328 unsigned int pin_type)
4329{
4330 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4331 pin_type);
4332 /* unmute pin */
d260cdf6
TI
4333 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4334 AMP_OUT_UNMUTE);
f6c7e546
TI
4335}
4336
df694daa
KY
4337static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4338 hda_nid_t nid, int pin_type,
e9edcee0
TI
4339 int dac_idx)
4340{
f6c7e546 4341 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4342 /* need the manual connection? */
4343 if (alc880_is_multi_pin(nid)) {
4344 struct alc_spec *spec = codec->spec;
4345 int idx = alc880_multi_pin_idx(nid);
4346 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4347 AC_VERB_SET_CONNECT_SEL,
4348 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4349 }
4350}
4351
baba8ee9
TI
4352static int get_pin_type(int line_out_type)
4353{
4354 if (line_out_type == AUTO_PIN_HP_OUT)
4355 return PIN_HP;
4356 else
4357 return PIN_OUT;
4358}
4359
e9edcee0
TI
4360static void alc880_auto_init_multi_out(struct hda_codec *codec)
4361{
4362 struct alc_spec *spec = codec->spec;
4363 int i;
ea1fb29a 4364
e9edcee0
TI
4365 for (i = 0; i < spec->autocfg.line_outs; i++) {
4366 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4367 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4368 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4369 }
4370}
4371
8d88bc3d 4372static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4373{
4374 struct alc_spec *spec = codec->spec;
4375 hda_nid_t pin;
4376
82bc955f 4377 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4378 if (pin) /* connect to front */
4379 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4380 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4381 if (pin) /* connect to front */
4382 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4383}
4384
4385static void alc880_auto_init_analog_input(struct hda_codec *codec)
4386{
4387 struct alc_spec *spec = codec->spec;
4388 int i;
4389
4390 for (i = 0; i < AUTO_PIN_LAST; i++) {
4391 hda_nid_t nid = spec->autocfg.input_pins[i];
4392 if (alc880_is_input_pin(nid)) {
23f0c048 4393 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4394 if (nid != ALC880_PIN_CD_NID &&
4395 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4396 snd_hda_codec_write(codec, nid, 0,
4397 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4398 AMP_OUT_MUTE);
4399 }
4400 }
4401}
4402
4403/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4404/* return 1 if successful, 0 if the proper config is not found,
4405 * or a negative error code
4406 */
e9edcee0
TI
4407static int alc880_parse_auto_config(struct hda_codec *codec)
4408{
4409 struct alc_spec *spec = codec->spec;
6a05ac4a 4410 int i, err;
df694daa 4411 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4412
f12ab1e0
TI
4413 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4414 alc880_ignore);
4415 if (err < 0)
e9edcee0 4416 return err;
f12ab1e0 4417 if (!spec->autocfg.line_outs)
e9edcee0 4418 return 0; /* can't find valid BIOS pin config */
df694daa 4419
f12ab1e0
TI
4420 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4421 if (err < 0)
4422 return err;
4423 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4424 if (err < 0)
4425 return err;
4426 err = alc880_auto_create_extra_out(spec,
4427 spec->autocfg.speaker_pins[0],
4428 "Speaker");
4429 if (err < 0)
4430 return err;
4431 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4432 "Headphone");
4433 if (err < 0)
4434 return err;
4435 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4436 if (err < 0)
e9edcee0
TI
4437 return err;
4438
4439 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4440
6a05ac4a
TI
4441 /* check multiple SPDIF-out (for recent codecs) */
4442 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4443 hda_nid_t dig_nid;
4444 err = snd_hda_get_connections(codec,
4445 spec->autocfg.dig_out_pins[i],
4446 &dig_nid, 1);
4447 if (err < 0)
4448 continue;
4449 if (!i)
4450 spec->multiout.dig_out_nid = dig_nid;
4451 else {
4452 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4453 spec->slave_dig_outs[i - 1] = dig_nid;
4454 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4455 break;
4456 }
4457 }
e9edcee0
TI
4458 if (spec->autocfg.dig_in_pin)
4459 spec->dig_in_nid = ALC880_DIGIN_NID;
4460
603c4019 4461 if (spec->kctls.list)
d88897ea 4462 add_mixer(spec, spec->kctls.list);
e9edcee0 4463
d88897ea 4464 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4465
a1e8d2da 4466 spec->num_mux_defs = 1;
61b9b9b1 4467 spec->input_mux = &spec->private_imux[0];
e9edcee0 4468
4a79ba34
TI
4469 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4470
e9edcee0
TI
4471 return 1;
4472}
4473
ae6b813a
TI
4474/* additional initialization for auto-configuration model */
4475static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4476{
f6c7e546 4477 struct alc_spec *spec = codec->spec;
e9edcee0 4478 alc880_auto_init_multi_out(codec);
8d88bc3d 4479 alc880_auto_init_extra_out(codec);
e9edcee0 4480 alc880_auto_init_analog_input(codec);
f6c7e546 4481 if (spec->unsol_event)
7fb0d78f 4482 alc_inithook(codec);
e9edcee0
TI
4483}
4484
f9e336f6
TI
4485static void set_capture_mixer(struct alc_spec *spec)
4486{
a23b688f
TI
4487 static struct snd_kcontrol_new *caps[2][3] = {
4488 { alc_capture_mixer_nosrc1,
4489 alc_capture_mixer_nosrc2,
4490 alc_capture_mixer_nosrc3 },
4491 { alc_capture_mixer1,
4492 alc_capture_mixer2,
4493 alc_capture_mixer3 },
f9e336f6 4494 };
a23b688f
TI
4495 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4496 int mux;
4497 if (spec->input_mux && spec->input_mux->num_items > 1)
4498 mux = 1;
4499 else
4500 mux = 0;
4501 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4502 }
f9e336f6
TI
4503}
4504
45bdd1c1
TI
4505#define set_beep_amp(spec, nid, idx, dir) \
4506 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4507
4508/*
4509 * OK, here we have finally the patch for ALC880
4510 */
4511
1da177e4
LT
4512static int patch_alc880(struct hda_codec *codec)
4513{
4514 struct alc_spec *spec;
4515 int board_config;
df694daa 4516 int err;
1da177e4 4517
e560d8d8 4518 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4519 if (spec == NULL)
4520 return -ENOMEM;
4521
4522 codec->spec = spec;
4523
f5fcc13c
TI
4524 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4525 alc880_models,
4526 alc880_cfg_tbl);
4527 if (board_config < 0) {
6c627f39
TI
4528 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4529 "trying auto-probe from BIOS...\n", codec->chip_name);
e9edcee0 4530 board_config = ALC880_AUTO;
1da177e4 4531 }
1da177e4 4532
e9edcee0
TI
4533 if (board_config == ALC880_AUTO) {
4534 /* automatic parse from the BIOS config */
4535 err = alc880_parse_auto_config(codec);
4536 if (err < 0) {
4537 alc_free(codec);
4538 return err;
f12ab1e0 4539 } else if (!err) {
9c7f852e
TI
4540 printk(KERN_INFO
4541 "hda_codec: Cannot set up configuration "
4542 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
4543 board_config = ALC880_3ST;
4544 }
1da177e4
LT
4545 }
4546
680cd536
KK
4547 err = snd_hda_attach_beep_device(codec, 0x1);
4548 if (err < 0) {
4549 alc_free(codec);
4550 return err;
4551 }
4552
df694daa
KY
4553 if (board_config != ALC880_AUTO)
4554 setup_preset(spec, &alc880_presets[board_config]);
1da177e4 4555
1da177e4
LT
4556 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4557 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 4558 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 4559
1da177e4
LT
4560 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4561 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4562
f12ab1e0 4563 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 4564 /* check whether NID 0x07 is valid */
54d17403 4565 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
4566 /* get type */
4567 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
4568 if (wcap != AC_WID_AUD_IN) {
4569 spec->adc_nids = alc880_adc_nids_alt;
4570 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
4571 } else {
4572 spec->adc_nids = alc880_adc_nids;
4573 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
4574 }
4575 }
f9e336f6 4576 set_capture_mixer(spec);
45bdd1c1 4577 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 4578
2134ea4f
TI
4579 spec->vmaster_nid = 0x0c;
4580
1da177e4 4581 codec->patch_ops = alc_patch_ops;
e9edcee0 4582 if (board_config == ALC880_AUTO)
ae6b813a 4583 spec->init_hook = alc880_auto_init;
cb53c626
TI
4584#ifdef CONFIG_SND_HDA_POWER_SAVE
4585 if (!spec->loopback.amplist)
4586 spec->loopback.amplist = alc880_loopbacks;
4587#endif
daead538 4588 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
4589
4590 return 0;
4591}
4592
e9edcee0 4593
1da177e4
LT
4594/*
4595 * ALC260 support
4596 */
4597
e9edcee0
TI
4598static hda_nid_t alc260_dac_nids[1] = {
4599 /* front */
4600 0x02,
4601};
4602
4603static hda_nid_t alc260_adc_nids[1] = {
4604 /* ADC0 */
4605 0x04,
4606};
4607
df694daa 4608static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4609 /* ADC1 */
4610 0x05,
4611};
4612
d57fdac0
JW
4613/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4614 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4615 */
4616static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4617 /* ADC0, ADC1 */
4618 0x04, 0x05
4619};
4620
e9edcee0
TI
4621#define ALC260_DIGOUT_NID 0x03
4622#define ALC260_DIGIN_NID 0x06
4623
4624static struct hda_input_mux alc260_capture_source = {
4625 .num_items = 4,
4626 .items = {
4627 { "Mic", 0x0 },
4628 { "Front Mic", 0x1 },
4629 { "Line", 0x2 },
4630 { "CD", 0x4 },
4631 },
4632};
4633
17e7aec6 4634/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4635 * headphone jack and the internal CD lines since these are the only pins at
4636 * which audio can appear. For flexibility, also allow the option of
4637 * recording the mixer output on the second ADC (ADC0 doesn't have a
4638 * connection to the mixer output).
a9430dd8 4639 */
a1e8d2da
JW
4640static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4641 {
4642 .num_items = 3,
4643 .items = {
4644 { "Mic/Line", 0x0 },
4645 { "CD", 0x4 },
4646 { "Headphone", 0x2 },
4647 },
a9430dd8 4648 },
a1e8d2da
JW
4649 {
4650 .num_items = 4,
4651 .items = {
4652 { "Mic/Line", 0x0 },
4653 { "CD", 0x4 },
4654 { "Headphone", 0x2 },
4655 { "Mixer", 0x5 },
4656 },
4657 },
4658
a9430dd8
JW
4659};
4660
a1e8d2da
JW
4661/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4662 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4663 */
a1e8d2da
JW
4664static struct hda_input_mux alc260_acer_capture_sources[2] = {
4665 {
4666 .num_items = 4,
4667 .items = {
4668 { "Mic", 0x0 },
4669 { "Line", 0x2 },
4670 { "CD", 0x4 },
4671 { "Headphone", 0x5 },
4672 },
4673 },
4674 {
4675 .num_items = 5,
4676 .items = {
4677 { "Mic", 0x0 },
4678 { "Line", 0x2 },
4679 { "CD", 0x4 },
4680 { "Headphone", 0x6 },
4681 { "Mixer", 0x5 },
4682 },
0bfc90e9
JW
4683 },
4684};
cc959489
MS
4685
4686/* Maxdata Favorit 100XS */
4687static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4688 {
4689 .num_items = 2,
4690 .items = {
4691 { "Line/Mic", 0x0 },
4692 { "CD", 0x4 },
4693 },
4694 },
4695 {
4696 .num_items = 3,
4697 .items = {
4698 { "Line/Mic", 0x0 },
4699 { "CD", 0x4 },
4700 { "Mixer", 0x5 },
4701 },
4702 },
4703};
4704
1da177e4
LT
4705/*
4706 * This is just place-holder, so there's something for alc_build_pcms to look
4707 * at when it calculates the maximum number of channels. ALC260 has no mixer
4708 * element which allows changing the channel mode, so the verb list is
4709 * never used.
4710 */
d2a6d7dc 4711static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4712 { 2, NULL },
4713};
4714
df694daa
KY
4715
4716/* Mixer combinations
4717 *
4718 * basic: base_output + input + pc_beep + capture
4719 * HP: base_output + input + capture_alt
4720 * HP_3013: hp_3013 + input + capture
4721 * fujitsu: fujitsu + capture
0bfc90e9 4722 * acer: acer + capture
df694daa
KY
4723 */
4724
4725static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4726 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4727 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4728 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4729 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4730 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4731 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4732 { } /* end */
f12ab1e0 4733};
1da177e4 4734
df694daa 4735static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4736 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4737 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4738 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4739 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4741 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4742 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4743 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4744 { } /* end */
4745};
4746
bec15c3a
TI
4747/* update HP, line and mono out pins according to the master switch */
4748static void alc260_hp_master_update(struct hda_codec *codec,
4749 hda_nid_t hp, hda_nid_t line,
4750 hda_nid_t mono)
4751{
4752 struct alc_spec *spec = codec->spec;
4753 unsigned int val = spec->master_sw ? PIN_HP : 0;
4754 /* change HP and line-out pins */
30cde0aa 4755 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 4756 val);
30cde0aa 4757 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4758 val);
4759 /* mono (speaker) depending on the HP jack sense */
4760 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 4761 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4762 val);
4763}
4764
4765static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4766 struct snd_ctl_elem_value *ucontrol)
4767{
4768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4769 struct alc_spec *spec = codec->spec;
4770 *ucontrol->value.integer.value = spec->master_sw;
4771 return 0;
4772}
4773
4774static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4775 struct snd_ctl_elem_value *ucontrol)
4776{
4777 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4778 struct alc_spec *spec = codec->spec;
4779 int val = !!*ucontrol->value.integer.value;
4780 hda_nid_t hp, line, mono;
4781
4782 if (val == spec->master_sw)
4783 return 0;
4784 spec->master_sw = val;
4785 hp = (kcontrol->private_value >> 16) & 0xff;
4786 line = (kcontrol->private_value >> 8) & 0xff;
4787 mono = kcontrol->private_value & 0xff;
4788 alc260_hp_master_update(codec, hp, line, mono);
4789 return 1;
4790}
4791
4792static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4793 {
4794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4795 .name = "Master Playback Switch",
4796 .info = snd_ctl_boolean_mono_info,
4797 .get = alc260_hp_master_sw_get,
4798 .put = alc260_hp_master_sw_put,
4799 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4800 },
4801 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4802 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4803 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4804 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4805 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4806 HDA_OUTPUT),
4807 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4808 { } /* end */
4809};
4810
4811static struct hda_verb alc260_hp_unsol_verbs[] = {
4812 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4813 {},
4814};
4815
4816static void alc260_hp_automute(struct hda_codec *codec)
4817{
4818 struct alc_spec *spec = codec->spec;
4819 unsigned int present;
4820
4821 present = snd_hda_codec_read(codec, 0x10, 0,
4822 AC_VERB_GET_PIN_SENSE, 0);
4823 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4824 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4825}
4826
4827static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4828{
4829 if ((res >> 26) == ALC880_HP_EVENT)
4830 alc260_hp_automute(codec);
4831}
4832
df694daa 4833static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4834 {
4835 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4836 .name = "Master Playback Switch",
4837 .info = snd_ctl_boolean_mono_info,
4838 .get = alc260_hp_master_sw_get,
4839 .put = alc260_hp_master_sw_put,
30cde0aa 4840 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 4841 },
df694daa
KY
4842 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4843 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4844 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4845 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4846 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4847 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4848 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4849 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4850 { } /* end */
4851};
4852
3f878308
KY
4853static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4854 .ops = &snd_hda_bind_vol,
4855 .values = {
4856 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4857 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4858 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4859 0
4860 },
4861};
4862
4863static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4864 .ops = &snd_hda_bind_sw,
4865 .values = {
4866 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4867 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4868 0
4869 },
4870};
4871
4872static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4873 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4874 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4875 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4877 { } /* end */
4878};
4879
bec15c3a
TI
4880static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4882 {},
4883};
4884
4885static void alc260_hp_3013_automute(struct hda_codec *codec)
4886{
4887 struct alc_spec *spec = codec->spec;
4888 unsigned int present;
4889
4890 present = snd_hda_codec_read(codec, 0x15, 0,
4891 AC_VERB_GET_PIN_SENSE, 0);
4892 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
30cde0aa 4893 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
4894}
4895
4896static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4897 unsigned int res)
4898{
4899 if ((res >> 26) == ALC880_HP_EVENT)
4900 alc260_hp_3013_automute(codec);
4901}
4902
3f878308
KY
4903static void alc260_hp_3012_automute(struct hda_codec *codec)
4904{
4905 unsigned int present, bits;
4906
4907 present = snd_hda_codec_read(codec, 0x10, 0,
4908 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4909
4910 bits = present ? 0 : PIN_OUT;
4911 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4912 bits);
4913 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4914 bits);
4915 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4916 bits);
4917}
4918
4919static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4920 unsigned int res)
4921{
4922 if ((res >> 26) == ALC880_HP_EVENT)
4923 alc260_hp_3012_automute(codec);
4924}
4925
4926/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4927 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4928 */
c8b6bf9b 4929static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4930 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4931 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4932 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4933 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4934 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4935 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4936 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4937 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
4938 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4939 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4940 { } /* end */
4941};
4942
a1e8d2da
JW
4943/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4944 * versions of the ALC260 don't act on requests to enable mic bias from NID
4945 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4946 * datasheet doesn't mention this restriction. At this stage it's not clear
4947 * whether this behaviour is intentional or is a hardware bug in chip
4948 * revisions available in early 2006. Therefore for now allow the
4949 * "Headphone Jack Mode" control to span all choices, but if it turns out
4950 * that the lack of mic bias for this NID is intentional we could change the
4951 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4952 *
4953 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4954 * don't appear to make the mic bias available from the "line" jack, even
4955 * though the NID used for this jack (0x14) can supply it. The theory is
4956 * that perhaps Acer have included blocking capacitors between the ALC260
4957 * and the output jack. If this turns out to be the case for all such
4958 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4959 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4960 *
4961 * The C20x Tablet series have a mono internal speaker which is controlled
4962 * via the chip's Mono sum widget and pin complex, so include the necessary
4963 * controls for such models. On models without a "mono speaker" the control
4964 * won't do anything.
a1e8d2da 4965 */
0bfc90e9
JW
4966static struct snd_kcontrol_new alc260_acer_mixer[] = {
4967 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4968 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4969 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4970 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4971 HDA_OUTPUT),
31bffaa9 4972 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4973 HDA_INPUT),
0bfc90e9
JW
4974 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4975 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4977 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4978 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4979 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4980 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4981 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
4982 { } /* end */
4983};
4984
cc959489
MS
4985/* Maxdata Favorit 100XS: one output and one input (0x12) jack
4986 */
4987static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4988 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4989 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4990 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4991 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4992 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4993 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4994 { } /* end */
4995};
4996
bc9f98a9
KY
4997/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4998 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4999 */
5000static struct snd_kcontrol_new alc260_will_mixer[] = {
5001 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5002 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5003 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5004 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5005 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5006 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5007 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5008 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5009 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5010 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5011 { } /* end */
5012};
5013
5014/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5015 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5016 */
5017static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5018 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5019 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5021 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5022 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5023 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5024 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5025 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5026 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5027 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5028 { } /* end */
5029};
5030
df694daa
KY
5031/*
5032 * initialization verbs
5033 */
1da177e4
LT
5034static struct hda_verb alc260_init_verbs[] = {
5035 /* Line In pin widget for input */
05acb863 5036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5037 /* CD pin widget for input */
05acb863 5038 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5039 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5040 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5041 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5042 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5043 /* LINE-2 is used for line-out in rear */
05acb863 5044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5045 /* select line-out */
fd56f2db 5046 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5047 /* LINE-OUT pin */
05acb863 5048 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5049 /* enable HP */
05acb863 5050 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5051 /* enable Mono */
05acb863
TI
5052 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5053 /* mute capture amp left and right */
16ded525 5054 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5055 /* set connection select to line in (default select for this ADC) */
5056 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5057 /* mute capture amp left and right */
5058 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5059 /* set connection select to line in (default select for this ADC) */
5060 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5061 /* set vol=0 Line-Out mixer amp left and right */
5062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5063 /* unmute pin widget amp left and right (no gain on this amp) */
5064 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5065 /* set vol=0 HP mixer amp left and right */
5066 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5067 /* unmute pin widget amp left and right (no gain on this amp) */
5068 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5069 /* set vol=0 Mono mixer amp left and right */
5070 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5071 /* unmute pin widget amp left and right (no gain on this amp) */
5072 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5073 /* unmute LINE-2 out pin */
5074 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5075 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5076 * Line In 2 = 0x03
5077 */
cb53c626
TI
5078 /* mute analog inputs */
5079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5084 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5085 /* mute Front out path */
5086 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5088 /* mute Headphone out path */
5089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5091 /* mute Mono out path */
5092 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5093 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5094 { }
5095};
5096
474167d6 5097#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5098static struct hda_verb alc260_hp_init_verbs[] = {
5099 /* Headphone and output */
5100 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5101 /* mono output */
5102 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5103 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5104 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5105 /* Mic2 (front panel) pin widget for input and vref at 80% */
5106 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5107 /* Line In pin widget for input */
5108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5109 /* Line-2 pin widget for output */
5110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5111 /* CD pin widget for input */
5112 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5113 /* unmute amp left and right */
5114 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5115 /* set connection select to line in (default select for this ADC) */
5116 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5117 /* unmute Line-Out mixer amp left and right (volume = 0) */
5118 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5119 /* mute pin widget amp left and right (no gain on this amp) */
5120 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5121 /* unmute HP mixer amp left and right (volume = 0) */
5122 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5123 /* mute pin widget amp left and right (no gain on this amp) */
5124 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5125 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5126 * Line In 2 = 0x03
5127 */
cb53c626
TI
5128 /* mute analog inputs */
5129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5134 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5135 /* Unmute Front out path */
5136 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5137 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5138 /* Unmute Headphone out path */
5139 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5140 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5141 /* Unmute Mono out path */
5142 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5143 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5144 { }
5145};
474167d6 5146#endif
df694daa
KY
5147
5148static struct hda_verb alc260_hp_3013_init_verbs[] = {
5149 /* Line out and output */
5150 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5151 /* mono output */
5152 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5153 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5154 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5155 /* Mic2 (front panel) pin widget for input and vref at 80% */
5156 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5157 /* Line In pin widget for input */
5158 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5159 /* Headphone pin widget for output */
5160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5161 /* CD pin widget for input */
5162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5163 /* unmute amp left and right */
5164 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5165 /* set connection select to line in (default select for this ADC) */
5166 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5167 /* unmute Line-Out mixer amp left and right (volume = 0) */
5168 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5169 /* mute pin widget amp left and right (no gain on this amp) */
5170 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5171 /* unmute HP mixer amp left and right (volume = 0) */
5172 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5173 /* mute pin widget amp left and right (no gain on this amp) */
5174 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5175 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5176 * Line In 2 = 0x03
5177 */
cb53c626
TI
5178 /* mute analog inputs */
5179 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5180 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5181 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5182 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5183 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5184 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5185 /* Unmute Front out path */
5186 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5188 /* Unmute Headphone out path */
5189 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5191 /* Unmute Mono out path */
5192 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5193 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5194 { }
5195};
5196
a9430dd8 5197/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5198 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5199 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5200 */
5201static struct hda_verb alc260_fujitsu_init_verbs[] = {
5202 /* Disable all GPIOs */
5203 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5204 /* Internal speaker is connected to headphone pin */
5205 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5206 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5208 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5209 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5210 /* Ensure all other unused pins are disabled and muted. */
5211 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5212 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5213 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5214 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5215 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5216 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5218 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5219
5220 /* Disable digital (SPDIF) pins */
5221 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5222 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5223
ea1fb29a 5224 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5225 * when acting as an output.
5226 */
5227 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5228
f7ace40d 5229 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5231 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5232 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5233 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5234 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5235 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5236 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5237 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5238 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5239
f7ace40d
JW
5240 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5241 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5242 /* Unmute Line1 pin widget output buffer since it starts as an output.
5243 * If the pin mode is changed by the user the pin mode control will
5244 * take care of enabling the pin's input/output buffers as needed.
5245 * Therefore there's no need to enable the input buffer at this
5246 * stage.
cdcd9268 5247 */
f7ace40d 5248 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5249 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5250 * mixer ctrl)
5251 */
f7ace40d
JW
5252 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5253
5254 /* Mute capture amp left and right */
5255 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5256 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5257 * in (on mic1 pin)
5258 */
5259 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5260
5261 /* Do the same for the second ADC: mute capture input amp and
5262 * set ADC connection to line in (on mic1 pin)
5263 */
5264 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5265 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5266
5267 /* Mute all inputs to mixer widget (even unconnected ones) */
5268 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5276
5277 { }
a9430dd8
JW
5278};
5279
0bfc90e9
JW
5280/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5281 * similar laptops (adapted from Fujitsu init verbs).
5282 */
5283static struct hda_verb alc260_acer_init_verbs[] = {
5284 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5285 * the headphone jack. Turn this on and rely on the standard mute
5286 * methods whenever the user wants to turn these outputs off.
5287 */
5288 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5289 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5290 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5291 /* Internal speaker/Headphone jack is connected to Line-out pin */
5292 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5293 /* Internal microphone/Mic jack is connected to Mic1 pin */
5294 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5295 /* Line In jack is connected to Line1 pin */
5296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5297 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5298 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5299 /* Ensure all other unused pins are disabled and muted. */
5300 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5301 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5302 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5303 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5304 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5305 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5306 /* Disable digital (SPDIF) pins */
5307 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5308 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5309
ea1fb29a 5310 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5311 * bus when acting as outputs.
5312 */
5313 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5314 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5315
5316 /* Start with output sum widgets muted and their output gains at min */
5317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5322 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5323 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5324 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5325 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5326
f12ab1e0
TI
5327 /* Unmute Line-out pin widget amp left and right
5328 * (no equiv mixer ctrl)
5329 */
0bfc90e9 5330 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5331 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5332 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5333 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5334 * inputs. If the pin mode is changed by the user the pin mode control
5335 * will take care of enabling the pin's input/output buffers as needed.
5336 * Therefore there's no need to enable the input buffer at this
5337 * stage.
5338 */
5339 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5340 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5341
5342 /* Mute capture amp left and right */
5343 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5344 /* Set ADC connection select to match default mixer setting - mic
5345 * (on mic1 pin)
5346 */
5347 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5348
5349 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5350 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5351 */
5352 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5353 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5354
5355 /* Mute all inputs to mixer widget (even unconnected ones) */
5356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5359 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5360 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5361 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5363 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5364
5365 { }
5366};
5367
cc959489
MS
5368/* Initialisation sequence for Maxdata Favorit 100XS
5369 * (adapted from Acer init verbs).
5370 */
5371static struct hda_verb alc260_favorit100_init_verbs[] = {
5372 /* GPIO 0 enables the output jack.
5373 * Turn this on and rely on the standard mute
5374 * methods whenever the user wants to turn these outputs off.
5375 */
5376 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5377 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5378 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5379 /* Line/Mic input jack is connected to Mic1 pin */
5380 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5381 /* Ensure all other unused pins are disabled and muted. */
5382 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5384 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5385 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5386 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5387 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5388 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5391 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5392 /* Disable digital (SPDIF) pins */
5393 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5394 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5395
5396 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5397 * bus when acting as outputs.
5398 */
5399 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5400 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5401
5402 /* Start with output sum widgets muted and their output gains at min */
5403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5406 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5408 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5409 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5410 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5411 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5412
5413 /* Unmute Line-out pin widget amp left and right
5414 * (no equiv mixer ctrl)
5415 */
5416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5417 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5418 * inputs. If the pin mode is changed by the user the pin mode control
5419 * will take care of enabling the pin's input/output buffers as needed.
5420 * Therefore there's no need to enable the input buffer at this
5421 * stage.
5422 */
5423 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5424
5425 /* Mute capture amp left and right */
5426 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5427 /* Set ADC connection select to match default mixer setting - mic
5428 * (on mic1 pin)
5429 */
5430 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5431
5432 /* Do similar with the second ADC: mute capture input amp and
5433 * set ADC connection to mic to match ALSA's default state.
5434 */
5435 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5436 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5437
5438 /* Mute all inputs to mixer widget (even unconnected ones) */
5439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5440 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5441 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5442 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5445 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5447
5448 { }
5449};
5450
bc9f98a9
KY
5451static struct hda_verb alc260_will_verbs[] = {
5452 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5453 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5454 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5455 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5456 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5457 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5458 {}
5459};
5460
5461static struct hda_verb alc260_replacer_672v_verbs[] = {
5462 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5463 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5464 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5465
5466 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5467 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5468 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5469
5470 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5471 {}
5472};
5473
5474/* toggle speaker-output according to the hp-jack state */
5475static void alc260_replacer_672v_automute(struct hda_codec *codec)
5476{
5477 unsigned int present;
5478
5479 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5480 present = snd_hda_codec_read(codec, 0x0f, 0,
5481 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5482 if (present) {
82beb8fd
TI
5483 snd_hda_codec_write_cache(codec, 0x01, 0,
5484 AC_VERB_SET_GPIO_DATA, 1);
5485 snd_hda_codec_write_cache(codec, 0x0f, 0,
5486 AC_VERB_SET_PIN_WIDGET_CONTROL,
5487 PIN_HP);
bc9f98a9 5488 } else {
82beb8fd
TI
5489 snd_hda_codec_write_cache(codec, 0x01, 0,
5490 AC_VERB_SET_GPIO_DATA, 0);
5491 snd_hda_codec_write_cache(codec, 0x0f, 0,
5492 AC_VERB_SET_PIN_WIDGET_CONTROL,
5493 PIN_OUT);
bc9f98a9
KY
5494 }
5495}
5496
5497static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5498 unsigned int res)
5499{
5500 if ((res >> 26) == ALC880_HP_EVENT)
5501 alc260_replacer_672v_automute(codec);
5502}
5503
3f878308
KY
5504static struct hda_verb alc260_hp_dc7600_verbs[] = {
5505 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5506 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5507 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5508 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5509 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5511 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5512 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5513 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5514 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5515 {}
5516};
5517
7cf51e48
JW
5518/* Test configuration for debugging, modelled after the ALC880 test
5519 * configuration.
5520 */
5521#ifdef CONFIG_SND_DEBUG
5522static hda_nid_t alc260_test_dac_nids[1] = {
5523 0x02,
5524};
5525static hda_nid_t alc260_test_adc_nids[2] = {
5526 0x04, 0x05,
5527};
a1e8d2da 5528/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 5529 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 5530 * is NID 0x04.
17e7aec6 5531 */
a1e8d2da
JW
5532static struct hda_input_mux alc260_test_capture_sources[2] = {
5533 {
5534 .num_items = 7,
5535 .items = {
5536 { "MIC1 pin", 0x0 },
5537 { "MIC2 pin", 0x1 },
5538 { "LINE1 pin", 0x2 },
5539 { "LINE2 pin", 0x3 },
5540 { "CD pin", 0x4 },
5541 { "LINE-OUT pin", 0x5 },
5542 { "HP-OUT pin", 0x6 },
5543 },
5544 },
5545 {
5546 .num_items = 8,
5547 .items = {
5548 { "MIC1 pin", 0x0 },
5549 { "MIC2 pin", 0x1 },
5550 { "LINE1 pin", 0x2 },
5551 { "LINE2 pin", 0x3 },
5552 { "CD pin", 0x4 },
5553 { "Mixer", 0x5 },
5554 { "LINE-OUT pin", 0x6 },
5555 { "HP-OUT pin", 0x7 },
5556 },
7cf51e48
JW
5557 },
5558};
5559static struct snd_kcontrol_new alc260_test_mixer[] = {
5560 /* Output driver widgets */
5561 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5562 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5563 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5564 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5565 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5566 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5567
a1e8d2da
JW
5568 /* Modes for retasking pin widgets
5569 * Note: the ALC260 doesn't seem to act on requests to enable mic
5570 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5571 * mention this restriction. At this stage it's not clear whether
5572 * this behaviour is intentional or is a hardware bug in chip
5573 * revisions available at least up until early 2006. Therefore for
5574 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5575 * choices, but if it turns out that the lack of mic bias for these
5576 * NIDs is intentional we could change their modes from
5577 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5578 */
7cf51e48
JW
5579 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5580 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5581 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5582 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5583 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5584 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5585
5586 /* Loopback mixer controls */
5587 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5588 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5589 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5590 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5591 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5592 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5593 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5594 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5595 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5596 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
5597 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5598 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5599 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5600 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
5601
5602 /* Controls for GPIO pins, assuming they are configured as outputs */
5603 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5604 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5605 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5606 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5607
92621f13
JW
5608 /* Switches to allow the digital IO pins to be enabled. The datasheet
5609 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 5610 * make this output available should provide clarification.
92621f13
JW
5611 */
5612 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5613 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5614
f8225f6d
JW
5615 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5616 * this output to turn on an external amplifier.
5617 */
5618 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5619 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5620
7cf51e48
JW
5621 { } /* end */
5622};
5623static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
5624 /* Enable all GPIOs as outputs with an initial value of 0 */
5625 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5626 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5627 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5628
7cf51e48
JW
5629 /* Enable retasking pins as output, initially without power amp */
5630 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5631 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5632 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5634 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5635 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5636
92621f13
JW
5637 /* Disable digital (SPDIF) pins initially, but users can enable
5638 * them via a mixer switch. In the case of SPDIF-out, this initverb
5639 * payload also sets the generation to 0, output to be in "consumer"
5640 * PCM format, copyright asserted, no pre-emphasis and no validity
5641 * control.
5642 */
7cf51e48
JW
5643 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5644 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5645
ea1fb29a 5646 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5647 * OUT1 sum bus when acting as an output.
5648 */
5649 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5650 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5651 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5652 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5653
5654 /* Start with output sum widgets muted and their output gains at min */
5655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5657 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5660 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5661 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5663 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5664
cdcd9268
JW
5665 /* Unmute retasking pin widget output buffers since the default
5666 * state appears to be output. As the pin mode is changed by the
5667 * user the pin mode control will take care of enabling the pin's
5668 * input/output buffers as needed.
5669 */
7cf51e48
JW
5670 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5671 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5673 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5674 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5675 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5676 /* Also unmute the mono-out pin widget */
5677 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5678
7cf51e48
JW
5679 /* Mute capture amp left and right */
5680 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5681 /* Set ADC connection select to match default mixer setting (mic1
5682 * pin)
7cf51e48
JW
5683 */
5684 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5685
5686 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5687 * set ADC connection to mic1 pin
7cf51e48
JW
5688 */
5689 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5690 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5691
5692 /* Mute all inputs to mixer widget (even unconnected ones) */
5693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5696 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5697 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5700 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5701
5702 { }
5703};
5704#endif
5705
6330079f
TI
5706#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5707#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5708
a3bcba38
TI
5709#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5710#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5711
df694daa
KY
5712/*
5713 * for BIOS auto-configuration
5714 */
16ded525 5715
df694daa 5716static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5717 const char *pfx, int *vol_bits)
df694daa
KY
5718{
5719 hda_nid_t nid_vol;
5720 unsigned long vol_val, sw_val;
5721 char name[32];
5722 int err;
5723
5724 if (nid >= 0x0f && nid < 0x11) {
5725 nid_vol = nid - 0x7;
5726 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5727 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5728 } else if (nid == 0x11) {
5729 nid_vol = nid - 0x7;
5730 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5731 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5732 } else if (nid >= 0x12 && nid <= 0x15) {
5733 nid_vol = 0x08;
5734 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5735 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5736 } else
5737 return 0; /* N/A */
ea1fb29a 5738
863b4518
TI
5739 if (!(*vol_bits & (1 << nid_vol))) {
5740 /* first control for the volume widget */
5741 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5742 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5743 if (err < 0)
5744 return err;
5745 *vol_bits |= (1 << nid_vol);
5746 }
df694daa 5747 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
5748 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5749 if (err < 0)
df694daa
KY
5750 return err;
5751 return 1;
5752}
5753
5754/* add playback controls from the parsed DAC table */
5755static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5756 const struct auto_pin_cfg *cfg)
5757{
5758 hda_nid_t nid;
5759 int err;
863b4518 5760 int vols = 0;
df694daa
KY
5761
5762 spec->multiout.num_dacs = 1;
5763 spec->multiout.dac_nids = spec->private_dac_nids;
5764 spec->multiout.dac_nids[0] = 0x02;
5765
5766 nid = cfg->line_out_pins[0];
5767 if (nid) {
863b4518 5768 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
df694daa
KY
5769 if (err < 0)
5770 return err;
5771 }
5772
82bc955f 5773 nid = cfg->speaker_pins[0];
df694daa 5774 if (nid) {
863b4518 5775 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
5776 if (err < 0)
5777 return err;
5778 }
5779
eb06ed8f 5780 nid = cfg->hp_pins[0];
df694daa 5781 if (nid) {
863b4518
TI
5782 err = alc260_add_playback_controls(spec, nid, "Headphone",
5783 &vols);
df694daa
KY
5784 if (err < 0)
5785 return err;
5786 }
f12ab1e0 5787 return 0;
df694daa
KY
5788}
5789
5790/* create playback/capture controls for input pins */
5791static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5792 const struct auto_pin_cfg *cfg)
5793{
61b9b9b1 5794 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
5795 int i, err, idx;
5796
5797 for (i = 0; i < AUTO_PIN_LAST; i++) {
5798 if (cfg->input_pins[i] >= 0x12) {
5799 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5800 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5801 auto_pin_cfg_labels[i], idx,
5802 0x07);
df694daa
KY
5803 if (err < 0)
5804 return err;
f12ab1e0
TI
5805 imux->items[imux->num_items].label =
5806 auto_pin_cfg_labels[i];
df694daa
KY
5807 imux->items[imux->num_items].index = idx;
5808 imux->num_items++;
5809 }
f12ab1e0 5810 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5811 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5812 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5813 auto_pin_cfg_labels[i], idx,
5814 0x07);
df694daa
KY
5815 if (err < 0)
5816 return err;
f12ab1e0
TI
5817 imux->items[imux->num_items].label =
5818 auto_pin_cfg_labels[i];
df694daa
KY
5819 imux->items[imux->num_items].index = idx;
5820 imux->num_items++;
5821 }
5822 }
5823 return 0;
5824}
5825
5826static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5827 hda_nid_t nid, int pin_type,
5828 int sel_idx)
5829{
f6c7e546 5830 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5831 /* need the manual connection? */
5832 if (nid >= 0x12) {
5833 int idx = nid - 0x12;
5834 snd_hda_codec_write(codec, idx + 0x0b, 0,
5835 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5836 }
5837}
5838
5839static void alc260_auto_init_multi_out(struct hda_codec *codec)
5840{
5841 struct alc_spec *spec = codec->spec;
5842 hda_nid_t nid;
5843
f12ab1e0 5844 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5845 if (nid) {
5846 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5847 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5848 }
ea1fb29a 5849
82bc955f 5850 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5851 if (nid)
5852 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5853
eb06ed8f 5854 nid = spec->autocfg.hp_pins[0];
df694daa 5855 if (nid)
baba8ee9 5856 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5857}
df694daa
KY
5858
5859#define ALC260_PIN_CD_NID 0x16
5860static void alc260_auto_init_analog_input(struct hda_codec *codec)
5861{
5862 struct alc_spec *spec = codec->spec;
5863 int i;
5864
5865 for (i = 0; i < AUTO_PIN_LAST; i++) {
5866 hda_nid_t nid = spec->autocfg.input_pins[i];
5867 if (nid >= 0x12) {
23f0c048 5868 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5869 if (nid != ALC260_PIN_CD_NID &&
5870 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5871 snd_hda_codec_write(codec, nid, 0,
5872 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5873 AMP_OUT_MUTE);
5874 }
5875 }
5876}
5877
5878/*
5879 * generic initialization of ADC, input mixers and output mixers
5880 */
5881static struct hda_verb alc260_volume_init_verbs[] = {
5882 /*
5883 * Unmute ADC0-1 and set the default input to mic-in
5884 */
5885 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5886 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5887 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5888 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5889
df694daa
KY
5890 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5891 * mixer widget
f12ab1e0
TI
5892 * Note: PASD motherboards uses the Line In 2 as the input for
5893 * front panel mic (mic 2)
df694daa
KY
5894 */
5895 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5896 /* mute analog inputs */
5897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5900 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5901 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5902
5903 /*
5904 * Set up output mixers (0x08 - 0x0a)
5905 */
5906 /* set vol=0 to output mixers */
5907 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5908 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5909 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5910 /* set up input amps for analog loopback */
5911 /* Amp Indices: DAC = 0, mixer = 1 */
5912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5913 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5914 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5915 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5916 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5917 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5918
df694daa
KY
5919 { }
5920};
5921
5922static int alc260_parse_auto_config(struct hda_codec *codec)
5923{
5924 struct alc_spec *spec = codec->spec;
df694daa
KY
5925 int err;
5926 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5927
f12ab1e0
TI
5928 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5929 alc260_ignore);
5930 if (err < 0)
df694daa 5931 return err;
f12ab1e0
TI
5932 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5933 if (err < 0)
4a471b7d 5934 return err;
603c4019 5935 if (!spec->kctls.list)
df694daa 5936 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5937 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5938 if (err < 0)
df694daa
KY
5939 return err;
5940
5941 spec->multiout.max_channels = 2;
5942
0852d7a6 5943 if (spec->autocfg.dig_outs)
df694daa 5944 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 5945 if (spec->kctls.list)
d88897ea 5946 add_mixer(spec, spec->kctls.list);
df694daa 5947
d88897ea 5948 add_verb(spec, alc260_volume_init_verbs);
df694daa 5949
a1e8d2da 5950 spec->num_mux_defs = 1;
61b9b9b1 5951 spec->input_mux = &spec->private_imux[0];
df694daa 5952
4a79ba34
TI
5953 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5954
df694daa
KY
5955 return 1;
5956}
5957
ae6b813a
TI
5958/* additional initialization for auto-configuration model */
5959static void alc260_auto_init(struct hda_codec *codec)
df694daa 5960{
f6c7e546 5961 struct alc_spec *spec = codec->spec;
df694daa
KY
5962 alc260_auto_init_multi_out(codec);
5963 alc260_auto_init_analog_input(codec);
f6c7e546 5964 if (spec->unsol_event)
7fb0d78f 5965 alc_inithook(codec);
df694daa
KY
5966}
5967
cb53c626
TI
5968#ifdef CONFIG_SND_HDA_POWER_SAVE
5969static struct hda_amp_list alc260_loopbacks[] = {
5970 { 0x07, HDA_INPUT, 0 },
5971 { 0x07, HDA_INPUT, 1 },
5972 { 0x07, HDA_INPUT, 2 },
5973 { 0x07, HDA_INPUT, 3 },
5974 { 0x07, HDA_INPUT, 4 },
5975 { } /* end */
5976};
5977#endif
5978
df694daa
KY
5979/*
5980 * ALC260 configurations
5981 */
f5fcc13c
TI
5982static const char *alc260_models[ALC260_MODEL_LAST] = {
5983 [ALC260_BASIC] = "basic",
5984 [ALC260_HP] = "hp",
5985 [ALC260_HP_3013] = "hp-3013",
2922c9af 5986 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
5987 [ALC260_FUJITSU_S702X] = "fujitsu",
5988 [ALC260_ACER] = "acer",
bc9f98a9
KY
5989 [ALC260_WILL] = "will",
5990 [ALC260_REPLACER_672V] = "replacer",
cc959489 5991 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 5992#ifdef CONFIG_SND_DEBUG
f5fcc13c 5993 [ALC260_TEST] = "test",
7cf51e48 5994#endif
f5fcc13c
TI
5995 [ALC260_AUTO] = "auto",
5996};
5997
5998static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5999 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 6000 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6001 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6002 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 6003 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 6004 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6005 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6006 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6007 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6008 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6009 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6010 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6011 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6012 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6013 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6014 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6015 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6016 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6017 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6018 {}
6019};
6020
6021static struct alc_config_preset alc260_presets[] = {
6022 [ALC260_BASIC] = {
6023 .mixers = { alc260_base_output_mixer,
45bdd1c1 6024 alc260_input_mixer },
df694daa
KY
6025 .init_verbs = { alc260_init_verbs },
6026 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6027 .dac_nids = alc260_dac_nids,
f9e336f6 6028 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
6029 .adc_nids = alc260_adc_nids,
6030 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6031 .channel_mode = alc260_modes,
6032 .input_mux = &alc260_capture_source,
6033 },
6034 [ALC260_HP] = {
bec15c3a 6035 .mixers = { alc260_hp_output_mixer,
f9e336f6 6036 alc260_input_mixer },
bec15c3a
TI
6037 .init_verbs = { alc260_init_verbs,
6038 alc260_hp_unsol_verbs },
df694daa
KY
6039 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6040 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6041 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6042 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6043 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6044 .channel_mode = alc260_modes,
6045 .input_mux = &alc260_capture_source,
bec15c3a
TI
6046 .unsol_event = alc260_hp_unsol_event,
6047 .init_hook = alc260_hp_automute,
df694daa 6048 },
3f878308
KY
6049 [ALC260_HP_DC7600] = {
6050 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6051 alc260_input_mixer },
3f878308
KY
6052 .init_verbs = { alc260_init_verbs,
6053 alc260_hp_dc7600_verbs },
6054 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6055 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6056 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6057 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6058 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6059 .channel_mode = alc260_modes,
6060 .input_mux = &alc260_capture_source,
6061 .unsol_event = alc260_hp_3012_unsol_event,
6062 .init_hook = alc260_hp_3012_automute,
6063 },
df694daa
KY
6064 [ALC260_HP_3013] = {
6065 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6066 alc260_input_mixer },
bec15c3a
TI
6067 .init_verbs = { alc260_hp_3013_init_verbs,
6068 alc260_hp_3013_unsol_verbs },
df694daa
KY
6069 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6070 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6071 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6072 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6073 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6074 .channel_mode = alc260_modes,
6075 .input_mux = &alc260_capture_source,
bec15c3a
TI
6076 .unsol_event = alc260_hp_3013_unsol_event,
6077 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6078 },
6079 [ALC260_FUJITSU_S702X] = {
f9e336f6 6080 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6081 .init_verbs = { alc260_fujitsu_init_verbs },
6082 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6083 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6084 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6085 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6086 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6087 .channel_mode = alc260_modes,
a1e8d2da
JW
6088 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6089 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6090 },
0bfc90e9 6091 [ALC260_ACER] = {
f9e336f6 6092 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6093 .init_verbs = { alc260_acer_init_verbs },
6094 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6095 .dac_nids = alc260_dac_nids,
6096 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6097 .adc_nids = alc260_dual_adc_nids,
6098 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6099 .channel_mode = alc260_modes,
a1e8d2da
JW
6100 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6101 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6102 },
cc959489
MS
6103 [ALC260_FAVORIT100] = {
6104 .mixers = { alc260_favorit100_mixer },
6105 .init_verbs = { alc260_favorit100_init_verbs },
6106 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6107 .dac_nids = alc260_dac_nids,
6108 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6109 .adc_nids = alc260_dual_adc_nids,
6110 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6111 .channel_mode = alc260_modes,
6112 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6113 .input_mux = alc260_favorit100_capture_sources,
6114 },
bc9f98a9 6115 [ALC260_WILL] = {
f9e336f6 6116 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6117 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6118 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6119 .dac_nids = alc260_dac_nids,
6120 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6121 .adc_nids = alc260_adc_nids,
6122 .dig_out_nid = ALC260_DIGOUT_NID,
6123 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6124 .channel_mode = alc260_modes,
6125 .input_mux = &alc260_capture_source,
6126 },
6127 [ALC260_REPLACER_672V] = {
f9e336f6 6128 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6129 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6130 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6131 .dac_nids = alc260_dac_nids,
6132 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6133 .adc_nids = alc260_adc_nids,
6134 .dig_out_nid = ALC260_DIGOUT_NID,
6135 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6136 .channel_mode = alc260_modes,
6137 .input_mux = &alc260_capture_source,
6138 .unsol_event = alc260_replacer_672v_unsol_event,
6139 .init_hook = alc260_replacer_672v_automute,
6140 },
7cf51e48
JW
6141#ifdef CONFIG_SND_DEBUG
6142 [ALC260_TEST] = {
f9e336f6 6143 .mixers = { alc260_test_mixer },
7cf51e48
JW
6144 .init_verbs = { alc260_test_init_verbs },
6145 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6146 .dac_nids = alc260_test_dac_nids,
6147 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6148 .adc_nids = alc260_test_adc_nids,
6149 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6150 .channel_mode = alc260_modes,
a1e8d2da
JW
6151 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6152 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6153 },
6154#endif
df694daa
KY
6155};
6156
6157static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6158{
6159 struct alc_spec *spec;
df694daa 6160 int err, board_config;
1da177e4 6161
e560d8d8 6162 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6163 if (spec == NULL)
6164 return -ENOMEM;
6165
6166 codec->spec = spec;
6167
f5fcc13c
TI
6168 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6169 alc260_models,
6170 alc260_cfg_tbl);
6171 if (board_config < 0) {
6c627f39
TI
6172 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6173 "trying auto-probe from BIOS...\n",
6174 codec->chip_name);
df694daa 6175 board_config = ALC260_AUTO;
16ded525 6176 }
1da177e4 6177
df694daa
KY
6178 if (board_config == ALC260_AUTO) {
6179 /* automatic parse from the BIOS config */
6180 err = alc260_parse_auto_config(codec);
6181 if (err < 0) {
6182 alc_free(codec);
6183 return err;
f12ab1e0 6184 } else if (!err) {
9c7f852e
TI
6185 printk(KERN_INFO
6186 "hda_codec: Cannot set up configuration "
6187 "from BIOS. Using base mode...\n");
df694daa
KY
6188 board_config = ALC260_BASIC;
6189 }
a9430dd8 6190 }
e9edcee0 6191
680cd536
KK
6192 err = snd_hda_attach_beep_device(codec, 0x1);
6193 if (err < 0) {
6194 alc_free(codec);
6195 return err;
6196 }
6197
df694daa
KY
6198 if (board_config != ALC260_AUTO)
6199 setup_preset(spec, &alc260_presets[board_config]);
1da177e4 6200
1da177e4
LT
6201 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6202 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6203
a3bcba38
TI
6204 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6205 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6206
4ef0ef19
TI
6207 if (!spec->adc_nids && spec->input_mux) {
6208 /* check whether NID 0x04 is valid */
6209 unsigned int wcap = get_wcaps(codec, 0x04);
6210 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6211 /* get type */
6212 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6213 spec->adc_nids = alc260_adc_nids_alt;
6214 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6215 } else {
6216 spec->adc_nids = alc260_adc_nids;
6217 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6218 }
6219 }
f9e336f6 6220 set_capture_mixer(spec);
45bdd1c1 6221 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6222
2134ea4f
TI
6223 spec->vmaster_nid = 0x08;
6224
1da177e4 6225 codec->patch_ops = alc_patch_ops;
df694daa 6226 if (board_config == ALC260_AUTO)
ae6b813a 6227 spec->init_hook = alc260_auto_init;
cb53c626
TI
6228#ifdef CONFIG_SND_HDA_POWER_SAVE
6229 if (!spec->loopback.amplist)
6230 spec->loopback.amplist = alc260_loopbacks;
6231#endif
daead538 6232 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
6233
6234 return 0;
6235}
6236
e9edcee0 6237
1da177e4
LT
6238/*
6239 * ALC882 support
6240 *
6241 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6242 * configuration. Each pin widget can choose any input DACs and a mixer.
6243 * Each ADC is connected from a mixer of all inputs. This makes possible
6244 * 6-channel independent captures.
6245 *
6246 * In addition, an independent DAC for the multi-playback (not used in this
6247 * driver yet).
6248 */
df694daa
KY
6249#define ALC882_DIGOUT_NID 0x06
6250#define ALC882_DIGIN_NID 0x0a
1da177e4 6251
d2a6d7dc 6252static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6253 { 8, NULL }
6254};
6255
6256static hda_nid_t alc882_dac_nids[4] = {
6257 /* front, rear, clfe, rear_surr */
6258 0x02, 0x03, 0x04, 0x05
6259};
6260
df694daa
KY
6261/* identical with ALC880 */
6262#define alc882_adc_nids alc880_adc_nids
6263#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 6264
e1406348
TI
6265static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6266static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6267
1da177e4
LT
6268/* input MUX */
6269/* FIXME: should be a matrix-type input source selection */
6270
6271static struct hda_input_mux alc882_capture_source = {
6272 .num_items = 4,
6273 .items = {
6274 { "Mic", 0x0 },
6275 { "Front Mic", 0x1 },
6276 { "Line", 0x2 },
6277 { "CD", 0x4 },
6278 },
6279};
41d5545d
KS
6280
6281static struct hda_input_mux mb5_capture_source = {
6282 .num_items = 3,
6283 .items = {
6284 { "Mic", 0x1 },
6285 { "Line", 0x2 },
6286 { "CD", 0x4 },
6287 },
6288};
6289
272a527c
KY
6290/*
6291 * 2ch mode
6292 */
6293static struct hda_verb alc882_3ST_ch2_init[] = {
6294 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6295 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6296 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6297 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6298 { } /* end */
6299};
6300
6301/*
6302 * 6ch mode
6303 */
6304static struct hda_verb alc882_3ST_ch6_init[] = {
6305 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6306 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6307 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6308 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6309 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6310 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6311 { } /* end */
6312};
6313
6314static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6315 { 2, alc882_3ST_ch2_init },
6316 { 6, alc882_3ST_ch6_init },
6317};
6318
df694daa
KY
6319/*
6320 * 6ch mode
6321 */
6322static struct hda_verb alc882_sixstack_ch6_init[] = {
6323 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6324 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6325 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6326 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6327 { } /* end */
6328};
6329
6330/*
6331 * 8ch mode
6332 */
6333static struct hda_verb alc882_sixstack_ch8_init[] = {
6334 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6335 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6336 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6337 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6338 { } /* end */
6339};
6340
6341static struct hda_channel_mode alc882_sixstack_modes[2] = {
6342 { 6, alc882_sixstack_ch6_init },
6343 { 8, alc882_sixstack_ch8_init },
6344};
6345
87350ad0
TI
6346/*
6347 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6348 */
6349
6350/*
6351 * 2ch mode
6352 */
6353static struct hda_verb alc885_mbp_ch2_init[] = {
6354 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6355 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6356 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6357 { } /* end */
6358};
6359
6360/*
6361 * 6ch mode
6362 */
6363static struct hda_verb alc885_mbp_ch6_init[] = {
6364 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6365 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6366 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6367 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6368 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6369 { } /* end */
6370};
6371
6372static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6373 { 2, alc885_mbp_ch2_init },
6374 { 6, alc885_mbp_ch6_init },
6375};
6376
92b9de83
KS
6377/*
6378 * 2ch
6379 * Speakers/Woofer/HP = Front
6380 * LineIn = Input
6381 */
6382static struct hda_verb alc885_mb5_ch2_init[] = {
6383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6385 { } /* end */
6386};
6387
6388/*
6389 * 6ch mode
6390 * Speakers/HP = Front
6391 * Woofer = LFE
6392 * LineIn = Surround
6393 */
6394static struct hda_verb alc885_mb5_ch6_init[] = {
6395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6397 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6398 { } /* end */
6399};
6400
6401static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6402 { 2, alc885_mb5_ch2_init },
6403 { 6, alc885_mb5_ch6_init },
6404};
87350ad0 6405
1da177e4
LT
6406/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6407 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6408 */
c8b6bf9b 6409static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 6410 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 6411 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 6412 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 6413 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
6414 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6415 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
6416 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6417 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 6418 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 6419 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
6420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6426 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
6427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6428 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6429 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 6430 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
6431 { } /* end */
6432};
6433
87350ad0 6434static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
6435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6436 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6437 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6438 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6439 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6440 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
6441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6442 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 6443 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
6444 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6445 { } /* end */
6446};
41d5545d
KS
6447
6448static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
6449 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6450 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6451 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6452 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6453 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6454 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6455 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6456 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
41d5545d
KS
6457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6458 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6460 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6461 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6462 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6463 { } /* end */
6464};
92b9de83 6465
bdd148a3
KY
6466static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6467 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6468 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6469 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6470 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6471 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6472 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6474 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6475 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
6476 { } /* end */
6477};
6478
272a527c
KY
6479static struct snd_kcontrol_new alc882_targa_mixer[] = {
6480 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6481 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6483 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6484 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6485 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6486 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6487 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6488 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6489 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6490 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6491 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 6492 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
6493 { } /* end */
6494};
6495
6496/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6497 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6498 */
6499static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6501 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6503 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6508 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6509 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6510 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6511 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6512 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6513 { } /* end */
6514};
6515
914759b7
TI
6516static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6518 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6520 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6521 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6522 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6523 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6525 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6526 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
6527 { } /* end */
6528};
6529
df694daa
KY
6530static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6531 {
6532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6533 .name = "Channel Mode",
6534 .info = alc_ch_mode_info,
6535 .get = alc_ch_mode_get,
6536 .put = alc_ch_mode_put,
6537 },
6538 { } /* end */
6539};
6540
1da177e4
LT
6541static struct hda_verb alc882_init_verbs[] = {
6542 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
6543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6546 /* Rear mixer */
05acb863
TI
6547 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6550 /* CLFE mixer */
05acb863
TI
6551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6554 /* Side mixer */
05acb863
TI
6555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6557 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6558
e9edcee0 6559 /* Front Pin: output 0 (0x0c) */
05acb863 6560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6562 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 6563 /* Rear Pin: output 1 (0x0d) */
05acb863 6564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6566 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 6567 /* CLFE Pin: output 2 (0x0e) */
05acb863 6568 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6569 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6570 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 6571 /* Side Pin: output 3 (0x0f) */
05acb863 6572 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6573 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6574 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 6575 /* Mic (rear) pin: input vref at 80% */
16ded525 6576 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6577 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6578 /* Front Mic pin: input vref at 80% */
16ded525 6579 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6580 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6581 /* Line In pin: input */
05acb863 6582 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
6583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6584 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6586 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6587 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6588 /* CD pin widget for input */
05acb863 6589 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
6590
6591 /* FIXME: use matrix-type input source selection */
6592 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6593 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
6594 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6595 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6596 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6597 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6598 /* Input mixer2 */
05acb863
TI
6599 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6600 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6601 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6602 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6603 /* Input mixer3 */
05acb863
TI
6604 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6605 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6608 /* ADC1: mute amp left and right */
6609 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6610 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6611 /* ADC2: mute amp left and right */
6612 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6613 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6614 /* ADC3: mute amp left and right */
6615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6616 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
6617
6618 { }
6619};
6620
4b146cb0
TI
6621static struct hda_verb alc882_eapd_verbs[] = {
6622 /* change to EAPD mode */
6623 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 6624 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 6625 { }
4b146cb0
TI
6626};
6627
9102cd1c
TD
6628/* Mac Pro test */
6629static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6630 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6631 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6632 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6633 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6634 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 6635 /* FIXME: this looks suspicious...
9102cd1c
TD
6636 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6637 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 6638 */
9102cd1c
TD
6639 { } /* end */
6640};
6641
6642static struct hda_verb alc882_macpro_init_verbs[] = {
6643 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6644 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6647 /* Front Pin: output 0 (0x0c) */
6648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6650 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6651 /* Front Mic pin: input vref at 80% */
6652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6654 /* Speaker: output */
6655 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6656 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6657 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6658 /* Headphone output (output 0 - 0x0c) */
6659 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6660 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6661 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6662
6663 /* FIXME: use matrix-type input source selection */
6664 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6665 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6670 /* Input mixer2 */
6671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6672 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6674 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6675 /* Input mixer3 */
6676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6680 /* ADC1: mute amp left and right */
6681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6682 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6683 /* ADC2: mute amp left and right */
6684 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6685 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6686 /* ADC3: mute amp left and right */
6687 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6688 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6689
6690 { }
6691};
f12ab1e0 6692
41d5545d
KS
6693/* Macbook 5,1 */
6694static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
6695 /* DACs */
6696 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6697 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6699 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 6700 /* Front mixer */
41d5545d
KS
6701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
6704 /* Surround mixer */
6705 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6706 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6707 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6708 /* LFE mixer */
6709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6710 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6712 /* HP mixer */
6713 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6714 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6715 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6716 /* Front Pin (0x0c) */
41d5545d
KS
6717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6718 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
6719 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6720 /* LFE Pin (0x0e) */
6721 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6723 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
6724 /* HP Pin (0x0f) */
41d5545d
KS
6725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 6727 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
41d5545d
KS
6728 /* Front Mic pin: input vref at 80% */
6729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6731 /* Line In pin */
6732 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6734
6735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6737 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6739 { }
6740};
6741
87350ad0
TI
6742/* Macbook Pro rev3 */
6743static struct hda_verb alc885_mbp3_init_verbs[] = {
6744 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6748 /* Rear mixer */
6749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6750 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6751 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6752 /* Front Pin: output 0 (0x0c) */
6753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6755 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6756 /* HP Pin: output 0 (0x0d) */
6757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6760 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6761 /* Mic (rear) pin: input vref at 80% */
6762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6763 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6764 /* Front Mic pin: input vref at 80% */
6765 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6767 /* Line In pin: use output 1 when in LineOut mode */
6768 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6770 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6771
6772 /* FIXME: use matrix-type input source selection */
6773 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6774 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6779 /* Input mixer2 */
6780 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6781 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6782 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6784 /* Input mixer3 */
6785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6789 /* ADC1: mute amp left and right */
6790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6791 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6792 /* ADC2: mute amp left and right */
6793 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6794 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6795 /* ADC3: mute amp left and right */
6796 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6797 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6798
6799 { }
6800};
6801
c54728d8
NF
6802/* iMac 24 mixer. */
6803static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6804 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6805 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6806 { } /* end */
6807};
6808
6809/* iMac 24 init verbs. */
6810static struct hda_verb alc885_imac24_init_verbs[] = {
6811 /* Internal speakers: output 0 (0x0c) */
6812 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6814 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6815 /* Internal speakers: output 0 (0x0c) */
6816 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6817 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6818 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6819 /* Headphone: output 0 (0x0c) */
6820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6822 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6823 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6824 /* Front Mic: input vref at 80% */
6825 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6826 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6827 { }
6828};
6829
6830/* Toggle speaker-output according to the hp-jack state */
a9fd4f3f 6831static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
c54728d8 6832{
a9fd4f3f 6833 struct alc_spec *spec = codec->spec;
c54728d8 6834
a9fd4f3f
TI
6835 spec->autocfg.hp_pins[0] = 0x14;
6836 spec->autocfg.speaker_pins[0] = 0x18;
6837 spec->autocfg.speaker_pins[1] = 0x1a;
6838 alc_automute_amp(codec);
c54728d8
NF
6839}
6840
a9fd4f3f 6841static void alc885_mbp3_init_hook(struct hda_codec *codec)
87350ad0 6842{
a9fd4f3f 6843 struct alc_spec *spec = codec->spec;
87350ad0 6844
a9fd4f3f
TI
6845 spec->autocfg.hp_pins[0] = 0x15;
6846 spec->autocfg.speaker_pins[0] = 0x14;
6847 alc_automute_amp(codec);
87350ad0
TI
6848}
6849
6850
272a527c
KY
6851static struct hda_verb alc882_targa_verbs[] = {
6852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6854
6855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6856 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6857
272a527c
KY
6858 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6859 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6860 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6861
6862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6863 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6864 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6865 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6866 { } /* end */
6867};
6868
6869/* toggle speaker-output according to the hp-jack state */
6870static void alc882_targa_automute(struct hda_codec *codec)
6871{
a9fd4f3f
TI
6872 struct alc_spec *spec = codec->spec;
6873 alc_automute_amp(codec);
82beb8fd 6874 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
6875 spec->jack_present ? 1 : 3);
6876}
6877
6878static void alc882_targa_init_hook(struct hda_codec *codec)
6879{
6880 struct alc_spec *spec = codec->spec;
6881
6882 spec->autocfg.hp_pins[0] = 0x14;
6883 spec->autocfg.speaker_pins[0] = 0x1b;
6884 alc882_targa_automute(codec);
272a527c
KY
6885}
6886
6887static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6888{
a9fd4f3f 6889 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 6890 alc882_targa_automute(codec);
272a527c
KY
6891}
6892
6893static struct hda_verb alc882_asus_a7j_verbs[] = {
6894 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6895 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6896
6897 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6900
272a527c
KY
6901 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6902 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6903 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6904
6905 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6906 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6907 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6908 { } /* end */
6909};
6910
914759b7
TI
6911static struct hda_verb alc882_asus_a7m_verbs[] = {
6912 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6913 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6914
6915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6917 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6918
914759b7
TI
6919 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6920 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6921 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6922
6923 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6924 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6925 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6926 { } /* end */
6927};
6928
9102cd1c
TD
6929static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6930{
6931 unsigned int gpiostate, gpiomask, gpiodir;
6932
6933 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6934 AC_VERB_GET_GPIO_DATA, 0);
6935
6936 if (!muted)
6937 gpiostate |= (1 << pin);
6938 else
6939 gpiostate &= ~(1 << pin);
6940
6941 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6942 AC_VERB_GET_GPIO_MASK, 0);
6943 gpiomask |= (1 << pin);
6944
6945 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6946 AC_VERB_GET_GPIO_DIRECTION, 0);
6947 gpiodir |= (1 << pin);
6948
6949
6950 snd_hda_codec_write(codec, codec->afg, 0,
6951 AC_VERB_SET_GPIO_MASK, gpiomask);
6952 snd_hda_codec_write(codec, codec->afg, 0,
6953 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6954
6955 msleep(1);
6956
6957 snd_hda_codec_write(codec, codec->afg, 0,
6958 AC_VERB_SET_GPIO_DATA, gpiostate);
6959}
6960
7debbe51
TI
6961/* set up GPIO at initialization */
6962static void alc885_macpro_init_hook(struct hda_codec *codec)
6963{
6964 alc882_gpio_mute(codec, 0, 0);
6965 alc882_gpio_mute(codec, 1, 0);
6966}
6967
6968/* set up GPIO and update auto-muting at initialization */
6969static void alc885_imac24_init_hook(struct hda_codec *codec)
6970{
6971 alc885_macpro_init_hook(codec);
a9fd4f3f 6972 alc885_imac24_automute_init_hook(codec);
7debbe51
TI
6973}
6974
df694daa
KY
6975/*
6976 * generic initialization of ADC, input mixers and output mixers
6977 */
6978static struct hda_verb alc882_auto_init_verbs[] = {
6979 /*
6980 * Unmute ADC0-2 and set the default input to mic-in
6981 */
6982 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6983 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6984 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6985 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6986 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6987 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6988
cb53c626 6989 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6990 * mixer widget
f12ab1e0
TI
6991 * Note: PASD motherboards uses the Line In 2 as the input for
6992 * front panel mic (mic 2)
df694daa
KY
6993 */
6994 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6995 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6996 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 7000
df694daa
KY
7001 /*
7002 * Set up output mixers (0x0c - 0x0f)
7003 */
7004 /* set vol=0 to output mixers */
7005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7006 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7009 /* set up input amps for analog loopback */
7010 /* Amp Indices: DAC = 0, mixer = 1 */
7011 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7012 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7013 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7014 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7015 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7018 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7019 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7020 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7021
7022 /* FIXME: use matrix-type input source selection */
7023 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7024 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7029 /* Input mixer2 */
7030 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7031 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7032 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7033 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7034 /* Input mixer3 */
7035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7039
7040 { }
7041};
7042
cb53c626
TI
7043#ifdef CONFIG_SND_HDA_POWER_SAVE
7044#define alc882_loopbacks alc880_loopbacks
7045#endif
7046
df694daa
KY
7047/* pcm configuration: identiacal with ALC880 */
7048#define alc882_pcm_analog_playback alc880_pcm_analog_playback
7049#define alc882_pcm_analog_capture alc880_pcm_analog_capture
7050#define alc882_pcm_digital_playback alc880_pcm_digital_playback
7051#define alc882_pcm_digital_capture alc880_pcm_digital_capture
7052
7053/*
7054 * configuration and preset
7055 */
f5fcc13c
TI
7056static const char *alc882_models[ALC882_MODEL_LAST] = {
7057 [ALC882_3ST_DIG] = "3stack-dig",
7058 [ALC882_6ST_DIG] = "6stack-dig",
7059 [ALC882_ARIMA] = "arima",
bdd148a3 7060 [ALC882_W2JC] = "w2jc",
0438a00e
TI
7061 [ALC882_TARGA] = "targa",
7062 [ALC882_ASUS_A7J] = "asus-a7j",
7063 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 7064 [ALC885_MACPRO] = "macpro",
41d5545d 7065 [ALC885_MB5] = "mb5",
87350ad0 7066 [ALC885_MBP3] = "mbp3",
c54728d8 7067 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
7068 [ALC882_AUTO] = "auto",
7069};
7070
7071static struct snd_pci_quirk alc882_cfg_tbl[] = {
7072 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 7073 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 7074 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 7075 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 7076 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 7077 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 7078 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 7079 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 7080 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
7081 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
7082 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
7083 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
7084 {}
7085};
7086
7087static struct alc_config_preset alc882_presets[] = {
7088 [ALC882_3ST_DIG] = {
7089 .mixers = { alc882_base_mixer },
7090 .init_verbs = { alc882_init_verbs },
7091 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7092 .dac_nids = alc882_dac_nids,
7093 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
7094 .dig_in_nid = ALC882_DIGIN_NID,
7095 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7096 .channel_mode = alc882_ch_modes,
4e195a7b 7097 .need_dac_fix = 1,
df694daa
KY
7098 .input_mux = &alc882_capture_source,
7099 },
7100 [ALC882_6ST_DIG] = {
7101 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7102 .init_verbs = { alc882_init_verbs },
7103 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7104 .dac_nids = alc882_dac_nids,
7105 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
7106 .dig_in_nid = ALC882_DIGIN_NID,
7107 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7108 .channel_mode = alc882_sixstack_modes,
7109 .input_mux = &alc882_capture_source,
7110 },
4b146cb0
TI
7111 [ALC882_ARIMA] = {
7112 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7113 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7114 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7115 .dac_nids = alc882_dac_nids,
7116 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7117 .channel_mode = alc882_sixstack_modes,
7118 .input_mux = &alc882_capture_source,
7119 },
bdd148a3
KY
7120 [ALC882_W2JC] = {
7121 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7122 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7123 alc880_gpio1_init_verbs },
7124 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7125 .dac_nids = alc882_dac_nids,
7126 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7127 .channel_mode = alc880_threestack_modes,
7128 .need_dac_fix = 1,
7129 .input_mux = &alc882_capture_source,
7130 .dig_out_nid = ALC882_DIGOUT_NID,
7131 },
87350ad0
TI
7132 [ALC885_MBP3] = {
7133 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7134 .init_verbs = { alc885_mbp3_init_verbs,
7135 alc880_gpio1_init_verbs },
7136 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7137 .dac_nids = alc882_dac_nids,
7138 .channel_mode = alc885_mbp_6ch_modes,
7139 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7140 .input_mux = &alc882_capture_source,
7141 .dig_out_nid = ALC882_DIGOUT_NID,
7142 .dig_in_nid = ALC882_DIGIN_NID,
a9fd4f3f
TI
7143 .unsol_event = alc_automute_amp_unsol_event,
7144 .init_hook = alc885_mbp3_init_hook,
87350ad0 7145 },
41d5545d 7146 [ALC885_MB5] = {
92b9de83 7147 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
41d5545d
KS
7148 .init_verbs = { alc885_mb5_init_verbs,
7149 alc880_gpio1_init_verbs },
7150 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7151 .dac_nids = alc882_dac_nids,
92b9de83
KS
7152 .channel_mode = alc885_mb5_6ch_modes,
7153 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
41d5545d
KS
7154 .input_mux = &mb5_capture_source,
7155 .dig_out_nid = ALC882_DIGOUT_NID,
7156 .dig_in_nid = ALC882_DIGIN_NID,
7157 },
9102cd1c
TD
7158 [ALC885_MACPRO] = {
7159 .mixers = { alc882_macpro_mixer },
7160 .init_verbs = { alc882_macpro_init_verbs },
7161 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7162 .dac_nids = alc882_dac_nids,
7163 .dig_out_nid = ALC882_DIGOUT_NID,
7164 .dig_in_nid = ALC882_DIGIN_NID,
7165 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7166 .channel_mode = alc882_ch_modes,
7167 .input_mux = &alc882_capture_source,
7debbe51 7168 .init_hook = alc885_macpro_init_hook,
9102cd1c 7169 },
c54728d8
NF
7170 [ALC885_IMAC24] = {
7171 .mixers = { alc885_imac24_mixer },
7172 .init_verbs = { alc885_imac24_init_verbs },
7173 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7174 .dac_nids = alc882_dac_nids,
7175 .dig_out_nid = ALC882_DIGOUT_NID,
7176 .dig_in_nid = ALC882_DIGIN_NID,
7177 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7178 .channel_mode = alc882_ch_modes,
7179 .input_mux = &alc882_capture_source,
a9fd4f3f 7180 .unsol_event = alc_automute_amp_unsol_event,
7debbe51 7181 .init_hook = alc885_imac24_init_hook,
c54728d8 7182 },
272a527c 7183 [ALC882_TARGA] = {
f9e336f6 7184 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
272a527c
KY
7185 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7186 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7187 .dac_nids = alc882_dac_nids,
7188 .dig_out_nid = ALC882_DIGOUT_NID,
7189 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7190 .adc_nids = alc882_adc_nids,
e1406348 7191 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
7192 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7193 .channel_mode = alc882_3ST_6ch_modes,
7194 .need_dac_fix = 1,
7195 .input_mux = &alc882_capture_source,
7196 .unsol_event = alc882_targa_unsol_event,
a9fd4f3f 7197 .init_hook = alc882_targa_init_hook,
272a527c
KY
7198 },
7199 [ALC882_ASUS_A7J] = {
f9e336f6 7200 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
272a527c
KY
7201 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7202 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7203 .dac_nids = alc882_dac_nids,
7204 .dig_out_nid = ALC882_DIGOUT_NID,
7205 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7206 .adc_nids = alc882_adc_nids,
e1406348 7207 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
7208 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7209 .channel_mode = alc882_3ST_6ch_modes,
7210 .need_dac_fix = 1,
7211 .input_mux = &alc882_capture_source,
ea1fb29a 7212 },
914759b7
TI
7213 [ALC882_ASUS_A7M] = {
7214 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7215 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7216 alc880_gpio1_init_verbs,
7217 alc882_asus_a7m_verbs },
7218 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7219 .dac_nids = alc882_dac_nids,
7220 .dig_out_nid = ALC882_DIGOUT_NID,
7221 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7222 .channel_mode = alc880_threestack_modes,
7223 .need_dac_fix = 1,
7224 .input_mux = &alc882_capture_source,
ea1fb29a 7225 },
df694daa
KY
7226};
7227
7228
f95474ec
TI
7229/*
7230 * Pin config fixes
7231 */
ea1fb29a 7232enum {
f95474ec
TI
7233 PINFIX_ABIT_AW9D_MAX
7234};
7235
7236static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7237 { 0x15, 0x01080104 }, /* side */
7238 { 0x16, 0x01011012 }, /* rear */
7239 { 0x17, 0x01016011 }, /* clfe */
7240 { }
7241};
7242
7243static const struct alc_pincfg *alc882_pin_fixes[] = {
7244 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7245};
7246
7247static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7248 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7249 {}
7250};
7251
df694daa
KY
7252/*
7253 * BIOS auto configuration
7254 */
7255static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7256 hda_nid_t nid, int pin_type,
7257 int dac_idx)
7258{
7259 /* set as output */
7260 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7261 int idx;
7262
f6c7e546 7263 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7264 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7265 idx = 4;
7266 else
7267 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
7268 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7269
7270}
7271
7272static void alc882_auto_init_multi_out(struct hda_codec *codec)
7273{
7274 struct alc_spec *spec = codec->spec;
7275 int i;
7276
7277 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7278 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7279 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 7280 if (nid)
baba8ee9 7281 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7282 i);
df694daa
KY
7283 }
7284}
7285
7286static void alc882_auto_init_hp_out(struct hda_codec *codec)
7287{
7288 struct alc_spec *spec = codec->spec;
7289 hda_nid_t pin;
7290
eb06ed8f 7291 pin = spec->autocfg.hp_pins[0];
df694daa 7292 if (pin) /* connect to front */
f12ab1e0
TI
7293 /* use dac 0 */
7294 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
7295 pin = spec->autocfg.speaker_pins[0];
7296 if (pin)
7297 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
7298}
7299
7300#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7301#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7302
7303static void alc882_auto_init_analog_input(struct hda_codec *codec)
7304{
7305 struct alc_spec *spec = codec->spec;
7306 int i;
7307
7308 for (i = 0; i < AUTO_PIN_LAST; i++) {
7309 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
7310 if (!nid)
7311 continue;
23f0c048 7312 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7194cae6
TI
7313 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7314 snd_hda_codec_write(codec, nid, 0,
7315 AC_VERB_SET_AMP_GAIN_MUTE,
7316 AMP_OUT_MUTE);
df694daa
KY
7317 }
7318}
7319
f511b01c
TI
7320static void alc882_auto_init_input_src(struct hda_codec *codec)
7321{
7322 struct alc_spec *spec = codec->spec;
f511b01c
TI
7323 int c;
7324
7325 for (c = 0; c < spec->num_adc_nids; c++) {
7326 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7327 hda_nid_t nid = spec->capsrc_nids[c];
b98b7b34
HRK
7328 unsigned int mux_idx;
7329 const struct hda_input_mux *imux;
f511b01c
TI
7330 int conns, mute, idx, item;
7331
7332 conns = snd_hda_get_connections(codec, nid, conn_list,
7333 ARRAY_SIZE(conn_list));
7334 if (conns < 0)
7335 continue;
b98b7b34
HRK
7336 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7337 imux = &spec->input_mux[mux_idx];
f511b01c
TI
7338 for (idx = 0; idx < conns; idx++) {
7339 /* if the current connection is the selected one,
7340 * unmute it as default - otherwise mute it
7341 */
7342 mute = AMP_IN_MUTE(idx);
7343 for (item = 0; item < imux->num_items; item++) {
7344 if (imux->items[item].index == idx) {
7345 if (spec->cur_mux[c] == item)
7346 mute = AMP_IN_UNMUTE(idx);
7347 break;
7348 }
7349 }
b98b7b34
HRK
7350 /* check if we have a selector or mixer
7351 * we could check for the widget type instead, but
7352 * just check for Amp-In presence (in case of mixer
7353 * without amp-in there is something wrong, this
7354 * function shouldn't be used or capsrc nid is wrong)
7355 */
7356 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7357 snd_hda_codec_write(codec, nid, 0,
7358 AC_VERB_SET_AMP_GAIN_MUTE,
7359 mute);
7360 else if (mute != AMP_IN_MUTE(idx))
7361 snd_hda_codec_write(codec, nid, 0,
7362 AC_VERB_SET_CONNECT_SEL,
7363 idx);
f511b01c
TI
7364 }
7365 }
7366}
7367
776e184e
TI
7368/* add mic boosts if needed */
7369static int alc_auto_add_mic_boost(struct hda_codec *codec)
7370{
7371 struct alc_spec *spec = codec->spec;
7372 int err;
7373 hda_nid_t nid;
7374
7375 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 7376 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7377 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7378 "Mic Boost",
7379 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7380 if (err < 0)
7381 return err;
7382 }
7383 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 7384 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7385 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7386 "Front Mic Boost",
7387 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7388 if (err < 0)
7389 return err;
7390 }
7391 return 0;
7392}
7393
df694daa
KY
7394/* almost identical with ALC880 parser... */
7395static int alc882_parse_auto_config(struct hda_codec *codec)
7396{
7397 struct alc_spec *spec = codec->spec;
7398 int err = alc880_parse_auto_config(codec);
7399
7400 if (err < 0)
7401 return err;
776e184e
TI
7402 else if (!err)
7403 return 0; /* no config found */
7404
7405 err = alc_auto_add_mic_boost(codec);
7406 if (err < 0)
7407 return err;
7408
7409 /* hack - override the init verbs */
7410 spec->init_verbs[0] = alc882_auto_init_verbs;
7411
7412 return 1; /* config found */
df694daa
KY
7413}
7414
ae6b813a
TI
7415/* additional initialization for auto-configuration model */
7416static void alc882_auto_init(struct hda_codec *codec)
df694daa 7417{
f6c7e546 7418 struct alc_spec *spec = codec->spec;
df694daa
KY
7419 alc882_auto_init_multi_out(codec);
7420 alc882_auto_init_hp_out(codec);
7421 alc882_auto_init_analog_input(codec);
f511b01c 7422 alc882_auto_init_input_src(codec);
f6c7e546 7423 if (spec->unsol_event)
7fb0d78f 7424 alc_inithook(codec);
df694daa
KY
7425}
7426
7943a8ab
TI
7427static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7428
df694daa
KY
7429static int patch_alc882(struct hda_codec *codec)
7430{
7431 struct alc_spec *spec;
7432 int err, board_config;
7433
7434 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7435 if (spec == NULL)
7436 return -ENOMEM;
7437
7438 codec->spec = spec;
7439
f5fcc13c
TI
7440 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7441 alc882_models,
7442 alc882_cfg_tbl);
df694daa
KY
7443
7444 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
7445 /* Pick up systems that don't supply PCI SSID */
7446 switch (codec->subsystem_id) {
7447 case 0x106b0c00: /* Mac Pro */
7448 board_config = ALC885_MACPRO;
7449 break;
c54728d8 7450 case 0x106b1000: /* iMac 24 */
f3911c5a 7451 case 0x106b2800: /* AppleTV */
3077e44c 7452 case 0x106b3e00: /* iMac 24 Aluminium */
c54728d8
NF
7453 board_config = ALC885_IMAC24;
7454 break;
2d466381 7455 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
c7e0757a 7456 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
9c95c43d 7457 case 0x106b00a4: /* MacbookPro4,1 */
87350ad0 7458 case 0x106b2c00: /* Macbook Pro rev3 */
eb4c41d3 7459 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
2a88464c 7460 case 0x106b3800: /* MacbookPro4,1 - latter revision */
87350ad0
TI
7461 board_config = ALC885_MBP3;
7462 break;
41d5545d 7463 case 0x106b3f00: /* Macbook 5,1 */
7442f9da
TI
7464 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7465 * seems not working, so apparently
7466 * no perfect solution yet
7467 */
41d5545d
KS
7468 board_config = ALC885_MB5;
7469 break;
081d17c4 7470 default:
7943a8ab 7471 /* ALC889A is handled better as ALC888-compatible */
669faba2
CM
7472 if (codec->revision_id == 0x100101 ||
7473 codec->revision_id == 0x100103) {
7943a8ab
TI
7474 alc_free(codec);
7475 return patch_alc883(codec);
7476 }
6c627f39
TI
7477 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7478 "trying auto-probe from BIOS...\n",
7479 codec->chip_name);
081d17c4
TD
7480 board_config = ALC882_AUTO;
7481 }
df694daa
KY
7482 }
7483
f95474ec
TI
7484 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7485
df694daa
KY
7486 if (board_config == ALC882_AUTO) {
7487 /* automatic parse from the BIOS config */
7488 err = alc882_parse_auto_config(codec);
7489 if (err < 0) {
7490 alc_free(codec);
7491 return err;
f12ab1e0 7492 } else if (!err) {
9c7f852e
TI
7493 printk(KERN_INFO
7494 "hda_codec: Cannot set up configuration "
7495 "from BIOS. Using base mode...\n");
df694daa
KY
7496 board_config = ALC882_3ST_DIG;
7497 }
7498 }
7499
680cd536
KK
7500 err = snd_hda_attach_beep_device(codec, 0x1);
7501 if (err < 0) {
7502 alc_free(codec);
7503 return err;
7504 }
7505
df694daa
KY
7506 if (board_config != ALC882_AUTO)
7507 setup_preset(spec, &alc882_presets[board_config]);
1da177e4 7508
df694daa
KY
7509 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7510 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
7511 /* FIXME: setup DAC5 */
7512 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7513 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 7514
df694daa
KY
7515 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7516 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 7517
61b9b9b1 7518 spec->capture_style = CAPT_MIX; /* matrix-style capture */
f12ab1e0 7519 if (!spec->adc_nids && spec->input_mux) {
df694daa 7520 /* check whether NID 0x07 is valid */
4a471b7d 7521 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
7522 /* get type */
7523 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
7524 if (wcap != AC_WID_AUD_IN) {
7525 spec->adc_nids = alc882_adc_nids_alt;
7526 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 7527 spec->capsrc_nids = alc882_capsrc_nids_alt;
df694daa
KY
7528 } else {
7529 spec->adc_nids = alc882_adc_nids;
7530 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 7531 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
7532 }
7533 }
f9e336f6 7534 set_capture_mixer(spec);
45bdd1c1 7535 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 7536
2134ea4f
TI
7537 spec->vmaster_nid = 0x0c;
7538
1da177e4 7539 codec->patch_ops = alc_patch_ops;
df694daa 7540 if (board_config == ALC882_AUTO)
ae6b813a 7541 spec->init_hook = alc882_auto_init;
cb53c626
TI
7542#ifdef CONFIG_SND_HDA_POWER_SAVE
7543 if (!spec->loopback.amplist)
7544 spec->loopback.amplist = alc882_loopbacks;
7545#endif
daead538 7546 codec->proc_widget_hook = print_realtek_coef;
df694daa
KY
7547
7548 return 0;
7549}
7550
7551/*
9c7f852e
TI
7552 * ALC883 support
7553 *
7554 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7555 * configuration. Each pin widget can choose any input DACs and a mixer.
7556 * Each ADC is connected from a mixer of all inputs. This makes possible
7557 * 6-channel independent captures.
7558 *
7559 * In addition, an independent DAC for the multi-playback (not used in this
7560 * driver yet).
df694daa 7561 */
9c7f852e
TI
7562#define ALC883_DIGOUT_NID 0x06
7563#define ALC883_DIGIN_NID 0x0a
df694daa 7564
3ab90935
WF
7565#define ALC1200_DIGOUT_NID 0x10
7566
9c7f852e
TI
7567static hda_nid_t alc883_dac_nids[4] = {
7568 /* front, rear, clfe, rear_surr */
f32a19e3 7569 0x02, 0x03, 0x04, 0x05
9c7f852e 7570};
df694daa 7571
9c7f852e
TI
7572static hda_nid_t alc883_adc_nids[2] = {
7573 /* ADC1-2 */
7574 0x08, 0x09,
7575};
f12ab1e0 7576
f9e336f6
TI
7577static hda_nid_t alc883_adc_nids_alt[1] = {
7578 /* ADC1 */
7579 0x08,
7580};
7581
5b2d1eca
VP
7582static hda_nid_t alc883_adc_nids_rev[2] = {
7583 /* ADC2-1 */
7584 0x09, 0x08
7585};
7586
61b9b9b1
HRK
7587#define alc889_adc_nids alc880_adc_nids
7588
e1406348
TI
7589static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7590
5b2d1eca
VP
7591static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7592
61b9b9b1
HRK
7593#define alc889_capsrc_nids alc882_capsrc_nids
7594
9c7f852e
TI
7595/* input MUX */
7596/* FIXME: should be a matrix-type input source selection */
df694daa 7597
9c7f852e
TI
7598static struct hda_input_mux alc883_capture_source = {
7599 .num_items = 4,
7600 .items = {
7601 { "Mic", 0x0 },
7602 { "Front Mic", 0x1 },
7603 { "Line", 0x2 },
7604 { "CD", 0x4 },
7605 },
7606};
bc9f98a9 7607
17bba1b7
J
7608static struct hda_input_mux alc883_3stack_6ch_intel = {
7609 .num_items = 4,
7610 .items = {
7611 { "Mic", 0x1 },
7612 { "Front Mic", 0x0 },
7613 { "Line", 0x2 },
7614 { "CD", 0x4 },
7615 },
7616};
7617
bc9f98a9
KY
7618static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7619 .num_items = 2,
7620 .items = {
7621 { "Mic", 0x1 },
7622 { "Line", 0x2 },
7623 },
7624};
7625
272a527c
KY
7626static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7627 .num_items = 4,
7628 .items = {
7629 { "Mic", 0x0 },
7630 { "iMic", 0x1 },
7631 { "Line", 0x2 },
7632 { "CD", 0x4 },
7633 },
7634};
7635
fb97dc67
J
7636static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7637 .num_items = 2,
7638 .items = {
7639 { "Mic", 0x0 },
7640 { "Int Mic", 0x1 },
7641 },
7642};
7643
e2757d5e
KY
7644static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7645 .num_items = 3,
7646 .items = {
7647 { "Mic", 0x0 },
7648 { "Front Mic", 0x1 },
7649 { "Line", 0x4 },
7650 },
7651};
7652
7653static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7654 .num_items = 2,
7655 .items = {
7656 { "Mic", 0x0 },
7657 { "Line", 0x2 },
7658 },
7659};
7660
eb4c41d3
TS
7661static struct hda_input_mux alc889A_mb31_capture_source = {
7662 .num_items = 2,
7663 .items = {
7664 { "Mic", 0x0 },
7665 /* Front Mic (0x01) unused */
7666 { "Line", 0x2 },
7667 /* Line 2 (0x03) unused */
7668 /* CD (0x04) unsused? */
7669 },
7670};
7671
9c7f852e
TI
7672/*
7673 * 2ch mode
7674 */
7675static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7676 { 2, NULL }
7677};
7678
7679/*
7680 * 2ch mode
7681 */
7682static struct hda_verb alc883_3ST_ch2_init[] = {
7683 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7684 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7685 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7686 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7687 { } /* end */
7688};
7689
b201131c
TD
7690/*
7691 * 4ch mode
7692 */
7693static struct hda_verb alc883_3ST_ch4_init[] = {
7694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7696 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7697 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7698 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7699 { } /* end */
7700};
7701
9c7f852e
TI
7702/*
7703 * 6ch mode
7704 */
7705static struct hda_verb alc883_3ST_ch6_init[] = {
7706 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7707 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7708 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7709 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7710 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7711 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7712 { } /* end */
7713};
7714
b201131c 7715static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 7716 { 2, alc883_3ST_ch2_init },
b201131c 7717 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
7718 { 6, alc883_3ST_ch6_init },
7719};
7720
17bba1b7
J
7721/*
7722 * 2ch mode
7723 */
7724static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7725 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7726 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7727 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7728 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7729 { } /* end */
7730};
7731
7732/*
7733 * 4ch mode
7734 */
7735static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7736 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7737 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7738 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7739 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7740 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7741 { } /* end */
7742};
7743
7744/*
7745 * 6ch mode
7746 */
7747static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7748 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7749 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7750 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7751 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7753 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7754 { } /* end */
7755};
7756
7757static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7758 { 2, alc883_3ST_ch2_intel_init },
7759 { 4, alc883_3ST_ch4_intel_init },
7760 { 6, alc883_3ST_ch6_intel_init },
7761};
7762
9c7f852e
TI
7763/*
7764 * 6ch mode
7765 */
7766static struct hda_verb alc883_sixstack_ch6_init[] = {
7767 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7768 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7769 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7770 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7771 { } /* end */
7772};
7773
7774/*
7775 * 8ch mode
7776 */
7777static struct hda_verb alc883_sixstack_ch8_init[] = {
7778 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7780 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7781 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7782 { } /* end */
7783};
7784
7785static struct hda_channel_mode alc883_sixstack_modes[2] = {
7786 { 6, alc883_sixstack_ch6_init },
7787 { 8, alc883_sixstack_ch8_init },
7788};
7789
eb4c41d3
TS
7790/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7791static struct hda_verb alc889A_mb31_ch2_init[] = {
7792 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7794 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7795 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7796 { } /* end */
7797};
7798
7799/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7800static struct hda_verb alc889A_mb31_ch4_init[] = {
7801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7802 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7803 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7804 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7805 { } /* end */
7806};
7807
7808/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7809static struct hda_verb alc889A_mb31_ch5_init[] = {
7810 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7811 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7812 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7813 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7814 { } /* end */
7815};
7816
7817/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7818static struct hda_verb alc889A_mb31_ch6_init[] = {
7819 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7820 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7823 { } /* end */
7824};
7825
7826static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7827 { 2, alc889A_mb31_ch2_init },
7828 { 4, alc889A_mb31_ch4_init },
7829 { 5, alc889A_mb31_ch5_init },
7830 { 6, alc889A_mb31_ch6_init },
7831};
7832
b373bdeb
AN
7833static struct hda_verb alc883_medion_eapd_verbs[] = {
7834 /* eanable EAPD on medion laptop */
7835 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7836 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7837 { }
7838};
7839
9c7f852e
TI
7840/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7841 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7842 */
7843
7844static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 7845 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
7846 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7847 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7848 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7849 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7850 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7851 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7852 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7854 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7855 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
7856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 7862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 7863 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7864 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
df694daa 7866 { } /* end */
834be88d
TI
7867};
7868
a8848bd6
AS
7869static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7870 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7871 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7872 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7874 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7875 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7878 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7881 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
7883 { } /* end */
7884};
7885
0c4cc443 7886static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7887 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7888 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7889 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7890 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7892 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7893 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7894 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7895 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7896 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
7897 { } /* end */
7898};
7899
fb97dc67
J
7900static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7901 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7902 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7903 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7904 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7906 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7908 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7909 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7910 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
7911 { } /* end */
7912};
7913
9c7f852e
TI
7914static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7918 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7919 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7921 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7922 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7923 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7925 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7926 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7927 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7928 { } /* end */
7929};
df694daa 7930
9c7f852e
TI
7931static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7932 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7933 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7934 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7935 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7936 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7937 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7938 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7939 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7941 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7942 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7944 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7946 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7947 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7949 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7950 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7951 { } /* end */
7952};
7953
17bba1b7
J
7954static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7955 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7956 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7957 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7958 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7959 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7960 HDA_OUTPUT),
7961 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7964 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7965 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7966 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7970 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7971 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7973 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7974 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
7975 { } /* end */
7976};
7977
d1d985f0 7978static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7982 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7983 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7988 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7989 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7991 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7996 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 7997 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
7998 { } /* end */
7999};
8000
ccc656ce
KY
8001static struct snd_kcontrol_new alc883_tagra_mixer[] = {
8002 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8004 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8005 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8006 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8007 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8008 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8009 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8010 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8011 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8012 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8013 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8014 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8016 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8017 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8018 { } /* end */
f12ab1e0 8019};
ccc656ce
KY
8020
8021static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
8022 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8023 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8024 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8028 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8029 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8030 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8031 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8032 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8033 { } /* end */
f12ab1e0 8034};
ccc656ce 8035
bc9f98a9
KY
8036static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8039 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8040 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8043 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8045 { } /* end */
f12ab1e0 8046};
bc9f98a9 8047
272a527c
KY
8048static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8049 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8050 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8052 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8053 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8056 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8057 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8058 { } /* end */
8059};
8060
8061static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8064 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8065 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8066 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8070 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8071 { } /* end */
ea1fb29a 8072};
272a527c 8073
2880a867 8074static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8075 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8076 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8077 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8078 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8079 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8080 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8081 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8083 { } /* end */
d1a991a6 8084};
2880a867 8085
e2757d5e
KY
8086static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8087 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8088 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8090 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8091 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8092 0x0d, 1, 0x0, HDA_OUTPUT),
8093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8096 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8097 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8098 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8099 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8100 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8101 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8106 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8107 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8108 { } /* end */
8109};
8110
eb4c41d3
TS
8111static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8112 /* Output mixers */
8113 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8114 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8115 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8116 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8117 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8118 HDA_OUTPUT),
8119 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8120 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8121 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8122 /* Output switches */
8123 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8124 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8125 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8126 /* Boost mixers */
8127 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8129 /* Input mixers */
8130 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8131 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8132 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8133 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8134 { } /* end */
8135};
8136
e2757d5e
KY
8137static struct hda_bind_ctls alc883_bind_cap_vol = {
8138 .ops = &snd_hda_bind_vol,
8139 .values = {
8140 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8141 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8142 0
8143 },
8144};
8145
8146static struct hda_bind_ctls alc883_bind_cap_switch = {
8147 .ops = &snd_hda_bind_sw,
8148 .values = {
8149 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8150 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8151 0
8152 },
8153};
8154
8155static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8156 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8157 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8158 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8159 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8160 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f9e336f6
TI
8164 { } /* end */
8165};
8166
8167static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
e2757d5e
KY
8168 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8169 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8170 {
8171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8172 /* .name = "Capture Source", */
8173 .name = "Input Source",
8174 .count = 1,
54cbc9ab
TI
8175 .info = alc_mux_enum_info,
8176 .get = alc_mux_enum_get,
8177 .put = alc_mux_enum_put,
e2757d5e
KY
8178 },
8179 { } /* end */
8180};
8181
9c7f852e
TI
8182static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8183 {
8184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8185 .name = "Channel Mode",
8186 .info = alc_ch_mode_info,
8187 .get = alc_ch_mode_get,
8188 .put = alc_ch_mode_put,
8189 },
8190 { } /* end */
8191};
8192
8193static struct hda_verb alc883_init_verbs[] = {
8194 /* ADC1: mute amp left and right */
e2757d5e 8195 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
df694daa 8196 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
8197 /* ADC2: mute amp left and right */
8198 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 8199 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
8200 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8201 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8203 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8204 /* Rear mixer */
8205 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8206 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8207 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8208 /* CLFE mixer */
8209 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8210 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8211 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8212 /* Side mixer */
8213 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8214 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8215 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 8216
cb53c626
TI
8217 /* mute analog input loopbacks */
8218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8220 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8221 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 8223
9c7f852e
TI
8224 /* Front Pin: output 0 (0x0c) */
8225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8227 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8228 /* Rear Pin: output 1 (0x0d) */
8229 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8230 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8231 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8232 /* CLFE Pin: output 2 (0x0e) */
8233 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8234 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8235 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8236 /* Side Pin: output 3 (0x0f) */
8237 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8238 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8239 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8240 /* Mic (rear) pin: input vref at 80% */
8241 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8242 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8243 /* Front Mic pin: input vref at 80% */
8244 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8245 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8246 /* Line In pin: input */
8247 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8248 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8250 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8251 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8252 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8253 /* CD pin widget for input */
8254 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8255
8256 /* FIXME: use matrix-type input source selection */
8257 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8258 /* Input mixer2 */
8259 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
8260 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8261 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8262 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8263 /* Input mixer3 */
8264 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
8265 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8266 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8268 { }
8269};
8270
a8848bd6 8271/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8272static void alc883_mitac_init_hook(struct hda_codec *codec)
a8848bd6 8273{
a9fd4f3f 8274 struct alc_spec *spec = codec->spec;
a8848bd6 8275
a9fd4f3f
TI
8276 spec->autocfg.hp_pins[0] = 0x15;
8277 spec->autocfg.speaker_pins[0] = 0x14;
8278 spec->autocfg.speaker_pins[1] = 0x17;
8279 alc_automute_amp(codec);
a8848bd6
AS
8280}
8281
8282/* auto-toggle front mic */
8283/*
8284static void alc883_mitac_mic_automute(struct hda_codec *codec)
8285{
8286 unsigned int present;
8287 unsigned char bits;
8288
8289 present = snd_hda_codec_read(codec, 0x18, 0,
8290 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8291 bits = present ? HDA_AMP_MUTE : 0;
8292 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8293}
8294*/
8295
a8848bd6
AS
8296static struct hda_verb alc883_mitac_verbs[] = {
8297 /* HP */
8298 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8300 /* Subwoofer */
8301 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8302 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8303
8304 /* enable unsolicited event */
8305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8306 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8307
8308 { } /* end */
8309};
8310
0c4cc443 8311static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8312 /* HP */
8313 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8315 /* Int speaker */
8316 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8318
8319 /* enable unsolicited event */
8320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8321 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8322
8323 { } /* end */
8324};
8325
fb97dc67
J
8326static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8327 /* HP */
8328 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8330 /* Subwoofer */
8331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8333
8334 /* enable unsolicited event */
8335 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8336
8337 { } /* end */
8338};
8339
ccc656ce
KY
8340static struct hda_verb alc883_tagra_verbs[] = {
8341 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8343
8344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8345 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8346
ccc656ce
KY
8347 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8348 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8349 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8350
8351 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
8352 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8353 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8354 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
8355
8356 { } /* end */
8357};
8358
bc9f98a9
KY
8359static struct hda_verb alc883_lenovo_101e_verbs[] = {
8360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8361 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8362 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8363 { } /* end */
8364};
8365
272a527c
KY
8366static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8367 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8369 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8370 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8371 { } /* end */
8372};
8373
8374static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8375 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8378 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8379 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8380 { } /* end */
8381};
8382
189609ae
KY
8383static struct hda_verb alc883_haier_w66_verbs[] = {
8384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8386
8387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388
8389 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8390 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8391 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8393 { } /* end */
8394};
8395
e2757d5e
KY
8396static struct hda_verb alc888_lenovo_sky_verbs[] = {
8397 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8398 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8399 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8401 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8402 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8403 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8404 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8405 { } /* end */
8406};
8407
8718b700
HRK
8408static struct hda_verb alc888_6st_dell_verbs[] = {
8409 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8410 { }
8411};
8412
a9fd4f3f 8413static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8718b700 8414{
a9fd4f3f 8415 struct alc_spec *spec = codec->spec;
8718b700 8416
a9fd4f3f
TI
8417 spec->autocfg.hp_pins[0] = 0x1b;
8418 spec->autocfg.speaker_pins[0] = 0x14;
8419 spec->autocfg.speaker_pins[1] = 0x16;
8420 spec->autocfg.speaker_pins[2] = 0x18;
8421 alc_automute_amp(codec);
8718b700
HRK
8422}
8423
4723c022 8424static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8425 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8426 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8427 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8428 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8429 { } /* end */
5795b9e6
CM
8430};
8431
3ea0d7cf
HRK
8432/*
8433 * 2ch mode
8434 */
4723c022 8435static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8438 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8439 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8440 { } /* end */
8341de60
CM
8441};
8442
3ea0d7cf
HRK
8443/*
8444 * 4ch mode
8445 */
8446static struct hda_verb alc888_3st_hp_4ch_init[] = {
8447 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8448 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8449 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8450 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8451 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8452 { } /* end */
8453};
8454
8455/*
8456 * 6ch mode
8457 */
4723c022 8458static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8459 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8460 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8461 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8462 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8463 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8464 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8465 { } /* end */
8341de60
CM
8466};
8467
3ea0d7cf 8468static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8469 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8470 { 4, alc888_3st_hp_4ch_init },
4723c022 8471 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8472};
8473
272a527c
KY
8474/* toggle front-jack and RCA according to the hp-jack state */
8475static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8476{
8477 unsigned int present;
ea1fb29a 8478
272a527c
KY
8479 present = snd_hda_codec_read(codec, 0x1b, 0,
8480 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8481 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8482 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8483 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8484 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8485}
8486
8487/* toggle RCA according to the front-jack state */
8488static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8489{
8490 unsigned int present;
ea1fb29a 8491
272a527c
KY
8492 present = snd_hda_codec_read(codec, 0x14, 0,
8493 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8494 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8495 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8496}
47fd830a 8497
272a527c
KY
8498static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8499 unsigned int res)
8500{
8501 if ((res >> 26) == ALC880_HP_EVENT)
8502 alc888_lenovo_ms7195_front_automute(codec);
8503 if ((res >> 26) == ALC880_FRONT_EVENT)
8504 alc888_lenovo_ms7195_rca_automute(codec);
8505}
8506
8507static struct hda_verb alc883_medion_md2_verbs[] = {
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8510
8511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8512
8513 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8514 { } /* end */
8515};
8516
8517/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8518static void alc883_medion_md2_init_hook(struct hda_codec *codec)
272a527c 8519{
a9fd4f3f 8520 struct alc_spec *spec = codec->spec;
272a527c 8521
a9fd4f3f
TI
8522 spec->autocfg.hp_pins[0] = 0x14;
8523 spec->autocfg.speaker_pins[0] = 0x15;
8524 alc_automute_amp(codec);
272a527c
KY
8525}
8526
ccc656ce 8527/* toggle speaker-output according to the hp-jack state */
a9fd4f3f
TI
8528#define alc883_tagra_init_hook alc882_targa_init_hook
8529#define alc883_tagra_unsol_event alc882_targa_unsol_event
368c7a95 8530
0c4cc443
HRK
8531static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8532{
8533 unsigned int present;
8534
8535 present = snd_hda_codec_read(codec, 0x18, 0,
8536 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8537 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8538 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8539}
8540
a9fd4f3f 8541static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
0c4cc443 8542{
a9fd4f3f
TI
8543 struct alc_spec *spec = codec->spec;
8544
8545 spec->autocfg.hp_pins[0] = 0x15;
8546 spec->autocfg.speaker_pins[0] = 0x14;
8547 alc_automute_amp(codec);
0c4cc443
HRK
8548 alc883_clevo_m720_mic_automute(codec);
8549}
8550
8551static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8552 unsigned int res)
8553{
0c4cc443 8554 switch (res >> 26) {
0c4cc443
HRK
8555 case ALC880_MIC_EVENT:
8556 alc883_clevo_m720_mic_automute(codec);
8557 break;
a9fd4f3f
TI
8558 default:
8559 alc_automute_amp_unsol_event(codec, res);
8560 break;
0c4cc443 8561 }
368c7a95
J
8562}
8563
fb97dc67 8564/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8565static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
fb97dc67 8566{
a9fd4f3f 8567 struct alc_spec *spec = codec->spec;
fb97dc67 8568
a9fd4f3f
TI
8569 spec->autocfg.hp_pins[0] = 0x14;
8570 spec->autocfg.speaker_pins[0] = 0x15;
8571 alc_automute_amp(codec);
fb97dc67
J
8572}
8573
a9fd4f3f 8574static void alc883_haier_w66_init_hook(struct hda_codec *codec)
fb97dc67 8575{
a9fd4f3f 8576 struct alc_spec *spec = codec->spec;
189609ae 8577
a9fd4f3f
TI
8578 spec->autocfg.hp_pins[0] = 0x1b;
8579 spec->autocfg.speaker_pins[0] = 0x14;
8580 alc_automute_amp(codec);
189609ae
KY
8581}
8582
bc9f98a9
KY
8583static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8584{
8585 unsigned int present;
f12ab1e0 8586 unsigned char bits;
bc9f98a9
KY
8587
8588 present = snd_hda_codec_read(codec, 0x14, 0,
8589 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8590 bits = present ? HDA_AMP_MUTE : 0;
8591 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8592 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8593}
8594
8595static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8596{
8597 unsigned int present;
f12ab1e0 8598 unsigned char bits;
bc9f98a9
KY
8599
8600 present = snd_hda_codec_read(codec, 0x1b, 0,
8601 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8602 bits = present ? HDA_AMP_MUTE : 0;
8603 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8604 HDA_AMP_MUTE, bits);
8605 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8606 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8607}
8608
8609static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8610 unsigned int res)
8611{
8612 if ((res >> 26) == ALC880_HP_EVENT)
8613 alc883_lenovo_101e_all_automute(codec);
8614 if ((res >> 26) == ALC880_FRONT_EVENT)
8615 alc883_lenovo_101e_ispeaker_automute(codec);
8616}
8617
676a9b53 8618/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8619static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
676a9b53 8620{
a9fd4f3f 8621 struct alc_spec *spec = codec->spec;
676a9b53 8622
a9fd4f3f
TI
8623 spec->autocfg.hp_pins[0] = 0x14;
8624 spec->autocfg.speaker_pins[0] = 0x15;
8625 spec->autocfg.speaker_pins[1] = 0x16;
8626 alc_automute_amp(codec);
676a9b53
TI
8627}
8628
d1a991a6
KY
8629static struct hda_verb alc883_acer_eapd_verbs[] = {
8630 /* HP Pin: output 0 (0x0c) */
8631 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8634 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8636 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8637 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8638 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8639 /* eanable EAPD on medion laptop */
8640 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8641 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8642 /* enable unsolicited event */
8643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8644 { }
8645};
8646
a9fd4f3f 8647static void alc888_6st_dell_init_hook(struct hda_codec *codec)
5795b9e6 8648{
a9fd4f3f 8649 struct alc_spec *spec = codec->spec;
5795b9e6 8650
a9fd4f3f
TI
8651 spec->autocfg.hp_pins[0] = 0x1b;
8652 spec->autocfg.speaker_pins[0] = 0x14;
8653 spec->autocfg.speaker_pins[1] = 0x15;
8654 spec->autocfg.speaker_pins[2] = 0x16;
8655 spec->autocfg.speaker_pins[3] = 0x17;
8656 alc_automute_amp(codec);
5795b9e6
CM
8657}
8658
a9fd4f3f 8659static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
e2757d5e 8660{
a9fd4f3f 8661 struct alc_spec *spec = codec->spec;
e2757d5e 8662
a9fd4f3f
TI
8663 spec->autocfg.hp_pins[0] = 0x1b;
8664 spec->autocfg.speaker_pins[0] = 0x14;
8665 spec->autocfg.speaker_pins[1] = 0x15;
8666 spec->autocfg.speaker_pins[2] = 0x16;
8667 spec->autocfg.speaker_pins[3] = 0x17;
8668 spec->autocfg.speaker_pins[4] = 0x1a;
8669 alc_automute_amp(codec);
e2757d5e
KY
8670}
8671
9c7f852e
TI
8672/*
8673 * generic initialization of ADC, input mixers and output mixers
8674 */
8675static struct hda_verb alc883_auto_init_verbs[] = {
8676 /*
8677 * Unmute ADC0-2 and set the default input to mic-in
8678 */
8679 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8680 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8681 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8682 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8683
cb53c626 8684 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8685 * mixer widget
f12ab1e0
TI
8686 * Note: PASD motherboards uses the Line In 2 as the input for
8687 * front panel mic (mic 2)
9c7f852e
TI
8688 */
8689 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8695
8696 /*
8697 * Set up output mixers (0x0c - 0x0f)
8698 */
8699 /* set vol=0 to output mixers */
8700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8703 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8704 /* set up input amps for analog loopback */
8705 /* Amp Indices: DAC = 0, mixer = 1 */
8706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8710 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8712 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8713 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8714 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8715 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8716
8717 /* FIXME: use matrix-type input source selection */
8718 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8719 /* Input mixer1 */
8720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8722 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8723 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
8724 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8725 /* Input mixer2 */
8726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8729 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 8730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
8731
8732 { }
8733};
8734
e2757d5e
KY
8735static struct hda_verb alc888_asus_m90v_verbs[] = {
8736 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8737 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8738 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8739 /* enable unsolicited event */
8740 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8741 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8742 { } /* end */
8743};
8744
8745static void alc883_nb_mic_automute(struct hda_codec *codec)
8746{
8747 unsigned int present;
8748
8749 present = snd_hda_codec_read(codec, 0x18, 0,
8750 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8751 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8752 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8753 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8754 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8755}
8756
a9fd4f3f 8757static void alc883_M90V_init_hook(struct hda_codec *codec)
e2757d5e 8758{
a9fd4f3f 8759 struct alc_spec *spec = codec->spec;
e2757d5e 8760
a9fd4f3f
TI
8761 spec->autocfg.hp_pins[0] = 0x1b;
8762 spec->autocfg.speaker_pins[0] = 0x14;
8763 spec->autocfg.speaker_pins[1] = 0x15;
8764 spec->autocfg.speaker_pins[2] = 0x16;
8765 alc_automute_pin(codec);
e2757d5e
KY
8766}
8767
8768static void alc883_mode2_unsol_event(struct hda_codec *codec,
8769 unsigned int res)
8770{
8771 switch (res >> 26) {
e2757d5e
KY
8772 case ALC880_MIC_EVENT:
8773 alc883_nb_mic_automute(codec);
8774 break;
a9fd4f3f
TI
8775 default:
8776 alc_sku_unsol_event(codec, res);
8777 break;
e2757d5e
KY
8778 }
8779}
8780
8781static void alc883_mode2_inithook(struct hda_codec *codec)
8782{
a9fd4f3f 8783 alc883_M90V_init_hook(codec);
e2757d5e
KY
8784 alc883_nb_mic_automute(codec);
8785}
8786
8787static struct hda_verb alc888_asus_eee1601_verbs[] = {
8788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8792 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8793 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8794 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8795 /* enable unsolicited event */
8796 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8797 { } /* end */
8798};
8799
e2757d5e
KY
8800static void alc883_eee1601_inithook(struct hda_codec *codec)
8801{
a9fd4f3f
TI
8802 struct alc_spec *spec = codec->spec;
8803
8804 spec->autocfg.hp_pins[0] = 0x14;
8805 spec->autocfg.speaker_pins[0] = 0x1b;
8806 alc_automute_pin(codec);
e2757d5e
KY
8807}
8808
eb4c41d3
TS
8809static struct hda_verb alc889A_mb31_verbs[] = {
8810 /* Init rear pin (used as headphone output) */
8811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8812 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8813 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8814 /* Init line pin (used as output in 4ch and 6ch mode) */
8815 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8816 /* Init line 2 pin (used as headphone out by default) */
8817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8819 { } /* end */
8820};
8821
8822/* Mute speakers according to the headphone jack state */
8823static void alc889A_mb31_automute(struct hda_codec *codec)
8824{
8825 unsigned int present;
8826
8827 /* Mute only in 2ch or 4ch mode */
8828 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8829 == 0x00) {
8830 present = snd_hda_codec_read(codec, 0x15, 0,
8831 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8832 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8833 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8834 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8835 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8836 }
8837}
8838
8839static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8840{
8841 if ((res >> 26) == ALC880_HP_EVENT)
8842 alc889A_mb31_automute(codec);
8843}
8844
cb53c626
TI
8845#ifdef CONFIG_SND_HDA_POWER_SAVE
8846#define alc883_loopbacks alc880_loopbacks
8847#endif
8848
9c7f852e
TI
8849/* pcm configuration: identiacal with ALC880 */
8850#define alc883_pcm_analog_playback alc880_pcm_analog_playback
8851#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 8852#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
8853#define alc883_pcm_digital_playback alc880_pcm_digital_playback
8854#define alc883_pcm_digital_capture alc880_pcm_digital_capture
8855
8856/*
8857 * configuration and preset
8858 */
f5fcc13c
TI
8859static const char *alc883_models[ALC883_MODEL_LAST] = {
8860 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8861 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8862 [ALC883_3ST_6ch] = "3stack-6ch",
8863 [ALC883_6ST_DIG] = "6stack-dig",
8864 [ALC883_TARGA_DIG] = "targa-dig",
8865 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 8866 [ALC883_ACER] = "acer",
2880a867 8867 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 8868 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
3b315d70 8869 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
f5fcc13c 8870 [ALC883_MEDION] = "medion",
272a527c 8871 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8872 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8873 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8874 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8875 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8876 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8877 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8878 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8879 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8880 [ALC883_MITAC] = "mitac",
0c4cc443 8881 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8882 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 8883 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 8884 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
3ab90935 8885 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 8886 [ALC889A_MB31] = "mb31",
f5fcc13c
TI
8887 [ALC883_AUTO] = "auto",
8888};
8889
8890static struct snd_pci_quirk alc883_cfg_tbl[] = {
8891 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741 8892 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 8893 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 8894 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
8895 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8896 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8897 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
8898 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8899 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd
LW
8900 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8901 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
8902 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8903 ALC888_ACER_ASPIRE_8930G),
b3bdb30b 8904 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
94683507 8905 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
a8e4f9dd
LW
8906 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8907 ALC888_ACER_ASPIRE_4930G),
cc374c47
JJGS
8908 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8909 ALC888_ACER_ASPIRE_4930G),
22b530e0
TI
8910 /* default Acer -- disabled as it causes more problems.
8911 * model=auto should work fine now
8912 */
8913 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
5795b9e6 8914 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 8915 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8916 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8917 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8918 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 8919 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 8920 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
a01c30cb 8921 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
ac3e3741 8922 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 8923 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 8924 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 8925 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
97ec710c 8926 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 8927 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
2de686d2 8928 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
8929 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8930 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8931 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8932 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 8933 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 8934 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8935 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8936 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 8937 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 8938 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8939 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8940 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8941 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8942 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8943 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8944 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8945 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8946 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8947 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8948 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
8949 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8950 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8951 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 8952 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 8953 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8954 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8955 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 8956 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8957 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8958 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8959 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
dea0a509 8960 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8961 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 8962 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 8963 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 8964 ALC883_FUJITSU_PI2515),
bfb53037 8965 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 8966 ALC888_FUJITSU_XA3530),
272a527c 8967 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8968 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8969 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8970 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8971 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8972 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 8973 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 8974 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8975 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
17bba1b7
J
8976 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8977 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 8978 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
4b558991 8979 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
ac3e3741 8980 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
8981 {}
8982};
8983
f3cd3f5d
WF
8984static hda_nid_t alc883_slave_dig_outs[] = {
8985 ALC1200_DIGOUT_NID, 0,
8986};
8987
b25c9da1
WF
8988static hda_nid_t alc1200_slave_dig_outs[] = {
8989 ALC883_DIGOUT_NID, 0,
8990};
8991
9c7f852e
TI
8992static struct alc_config_preset alc883_presets[] = {
8993 [ALC883_3ST_2ch_DIG] = {
8994 .mixers = { alc883_3ST_2ch_mixer },
8995 .init_verbs = { alc883_init_verbs },
8996 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8997 .dac_nids = alc883_dac_nids,
8998 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8999 .dig_in_nid = ALC883_DIGIN_NID,
9000 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9001 .channel_mode = alc883_3ST_2ch_modes,
9002 .input_mux = &alc883_capture_source,
9003 },
9004 [ALC883_3ST_6ch_DIG] = {
9005 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9006 .init_verbs = { alc883_init_verbs },
9007 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9008 .dac_nids = alc883_dac_nids,
9009 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9010 .dig_in_nid = ALC883_DIGIN_NID,
9011 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9012 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9013 .need_dac_fix = 1,
9c7f852e 9014 .input_mux = &alc883_capture_source,
f12ab1e0 9015 },
9c7f852e
TI
9016 [ALC883_3ST_6ch] = {
9017 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9018 .init_verbs = { alc883_init_verbs },
9019 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9020 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9021 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9022 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9023 .need_dac_fix = 1,
9c7f852e 9024 .input_mux = &alc883_capture_source,
f12ab1e0 9025 },
17bba1b7
J
9026 [ALC883_3ST_6ch_INTEL] = {
9027 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9028 .init_verbs = { alc883_init_verbs },
9029 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9030 .dac_nids = alc883_dac_nids,
9031 .dig_out_nid = ALC883_DIGOUT_NID,
9032 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9033 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9034 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9035 .channel_mode = alc883_3ST_6ch_intel_modes,
9036 .need_dac_fix = 1,
9037 .input_mux = &alc883_3stack_6ch_intel,
9038 },
9c7f852e
TI
9039 [ALC883_6ST_DIG] = {
9040 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9041 .init_verbs = { alc883_init_verbs },
9042 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9043 .dac_nids = alc883_dac_nids,
9044 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9045 .dig_in_nid = ALC883_DIGIN_NID,
9046 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9047 .channel_mode = alc883_sixstack_modes,
9048 .input_mux = &alc883_capture_source,
9049 },
ccc656ce
KY
9050 [ALC883_TARGA_DIG] = {
9051 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
9052 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
9053 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9054 .dac_nids = alc883_dac_nids,
9055 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9056 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9057 .channel_mode = alc883_3ST_6ch_modes,
9058 .need_dac_fix = 1,
9059 .input_mux = &alc883_capture_source,
9060 .unsol_event = alc883_tagra_unsol_event,
a9fd4f3f 9061 .init_hook = alc883_tagra_init_hook,
ccc656ce
KY
9062 },
9063 [ALC883_TARGA_2ch_DIG] = {
9064 .mixers = { alc883_tagra_2ch_mixer},
9065 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
9066 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9067 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9068 .adc_nids = alc883_adc_nids_alt,
9069 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
ccc656ce 9070 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9071 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9072 .channel_mode = alc883_3ST_2ch_modes,
9073 .input_mux = &alc883_capture_source,
9074 .unsol_event = alc883_tagra_unsol_event,
a9fd4f3f 9075 .init_hook = alc883_tagra_init_hook,
ccc656ce 9076 },
bab282b9 9077 [ALC883_ACER] = {
676a9b53 9078 .mixers = { alc883_base_mixer },
bab282b9
VA
9079 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9080 * and the headphone jack. Turn this on and rely on the
9081 * standard mute methods whenever the user wants to turn
9082 * these outputs off.
9083 */
9084 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9085 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9086 .dac_nids = alc883_dac_nids,
bab282b9
VA
9087 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9088 .channel_mode = alc883_3ST_2ch_modes,
9089 .input_mux = &alc883_capture_source,
9090 },
2880a867 9091 [ALC883_ACER_ASPIRE] = {
676a9b53 9092 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 9093 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
9094 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9095 .dac_nids = alc883_dac_nids,
9096 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
9097 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9098 .channel_mode = alc883_3ST_2ch_modes,
9099 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
9100 .unsol_event = alc_automute_amp_unsol_event,
9101 .init_hook = alc883_acer_aspire_init_hook,
d1a991a6 9102 },
5b2d1eca 9103 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 9104 .mixers = { alc888_base_mixer,
5b2d1eca
VP
9105 alc883_chmode_mixer },
9106 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9107 alc888_acer_aspire_4930g_verbs },
9108 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9109 .dac_nids = alc883_dac_nids,
9110 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9111 .adc_nids = alc883_adc_nids_rev,
9112 .capsrc_nids = alc883_capsrc_nids_rev,
9113 .dig_out_nid = ALC883_DIGOUT_NID,
9114 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9115 .channel_mode = alc883_3ST_6ch_modes,
9116 .need_dac_fix = 1,
9117 .num_mux_defs =
ef8ef5fb
VP
9118 ARRAY_SIZE(alc888_2_capture_sources),
9119 .input_mux = alc888_2_capture_sources,
a9fd4f3f
TI
9120 .unsol_event = alc_automute_amp_unsol_event,
9121 .init_hook = alc888_acer_aspire_4930g_init_hook,
5b2d1eca 9122 },
3b315d70
HM
9123 [ALC888_ACER_ASPIRE_8930G] = {
9124 .mixers = { alc888_base_mixer,
9125 alc883_chmode_mixer },
9126 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
018df418 9127 alc889_acer_aspire_8930g_verbs },
3b315d70
HM
9128 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9129 .dac_nids = alc883_dac_nids,
018df418
HM
9130 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9131 .adc_nids = alc889_adc_nids,
9132 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
9133 .dig_out_nid = ALC883_DIGOUT_NID,
9134 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9135 .channel_mode = alc883_3ST_6ch_modes,
9136 .need_dac_fix = 1,
9137 .const_channel_count = 6,
9138 .num_mux_defs =
018df418
HM
9139 ARRAY_SIZE(alc889_capture_sources),
9140 .input_mux = alc889_capture_sources,
3b315d70 9141 .unsol_event = alc_automute_amp_unsol_event,
018df418 9142 .init_hook = alc889_acer_aspire_8930g_init_hook,
3b315d70 9143 },
c07584c8
TD
9144 [ALC883_MEDION] = {
9145 .mixers = { alc883_fivestack_mixer,
9146 alc883_chmode_mixer },
9147 .init_verbs = { alc883_init_verbs,
b373bdeb 9148 alc883_medion_eapd_verbs },
c07584c8
TD
9149 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9150 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9151 .adc_nids = alc883_adc_nids_alt,
9152 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
c07584c8
TD
9153 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9154 .channel_mode = alc883_sixstack_modes,
9155 .input_mux = &alc883_capture_source,
b373bdeb 9156 },
272a527c
KY
9157 [ALC883_MEDION_MD2] = {
9158 .mixers = { alc883_medion_md2_mixer},
9159 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9160 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9161 .dac_nids = alc883_dac_nids,
9162 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9163 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9164 .channel_mode = alc883_3ST_2ch_modes,
9165 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
9166 .unsol_event = alc_automute_amp_unsol_event,
9167 .init_hook = alc883_medion_md2_init_hook,
ea1fb29a 9168 },
b373bdeb 9169 [ALC883_LAPTOP_EAPD] = {
676a9b53 9170 .mixers = { alc883_base_mixer },
b373bdeb
AN
9171 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9172 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9173 .dac_nids = alc883_dac_nids,
b373bdeb
AN
9174 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9175 .channel_mode = alc883_3ST_2ch_modes,
9176 .input_mux = &alc883_capture_source,
9177 },
0c4cc443
HRK
9178 [ALC883_CLEVO_M720] = {
9179 .mixers = { alc883_clevo_m720_mixer },
9180 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
9181 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9182 .dac_nids = alc883_dac_nids,
9183 .dig_out_nid = ALC883_DIGOUT_NID,
9184 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9185 .channel_mode = alc883_3ST_2ch_modes,
9186 .input_mux = &alc883_capture_source,
0c4cc443 9187 .unsol_event = alc883_clevo_m720_unsol_event,
a9fd4f3f 9188 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 9189 },
bc9f98a9
KY
9190 [ALC883_LENOVO_101E_2ch] = {
9191 .mixers = { alc883_lenovo_101e_2ch_mixer},
9192 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9193 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9194 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9195 .adc_nids = alc883_adc_nids_alt,
9196 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
bc9f98a9
KY
9197 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9198 .channel_mode = alc883_3ST_2ch_modes,
9199 .input_mux = &alc883_lenovo_101e_capture_source,
9200 .unsol_event = alc883_lenovo_101e_unsol_event,
9201 .init_hook = alc883_lenovo_101e_all_automute,
9202 },
272a527c
KY
9203 [ALC883_LENOVO_NB0763] = {
9204 .mixers = { alc883_lenovo_nb0763_mixer },
9205 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9207 .dac_nids = alc883_dac_nids,
272a527c
KY
9208 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9209 .channel_mode = alc883_3ST_2ch_modes,
9210 .need_dac_fix = 1,
9211 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f
TI
9212 .unsol_event = alc_automute_amp_unsol_event,
9213 .init_hook = alc883_medion_md2_init_hook,
272a527c
KY
9214 },
9215 [ALC888_LENOVO_MS7195_DIG] = {
9216 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9217 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9218 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9219 .dac_nids = alc883_dac_nids,
9220 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9221 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9222 .channel_mode = alc883_3ST_6ch_modes,
9223 .need_dac_fix = 1,
9224 .input_mux = &alc883_capture_source,
9225 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9226 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
9227 },
9228 [ALC883_HAIER_W66] = {
9229 .mixers = { alc883_tagra_2ch_mixer},
9230 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9231 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9232 .dac_nids = alc883_dac_nids,
9233 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
9234 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9235 .channel_mode = alc883_3ST_2ch_modes,
9236 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
9237 .unsol_event = alc_automute_amp_unsol_event,
9238 .init_hook = alc883_haier_w66_init_hook,
eea6419e 9239 },
4723c022 9240 [ALC888_3ST_HP] = {
eea6419e 9241 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 9242 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
9243 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9244 .dac_nids = alc883_dac_nids,
4723c022
CM
9245 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9246 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
9247 .need_dac_fix = 1,
9248 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
9249 .unsol_event = alc_automute_amp_unsol_event,
9250 .init_hook = alc888_3st_hp_init_hook,
8341de60 9251 },
5795b9e6 9252 [ALC888_6ST_DELL] = {
f24dbdc6 9253 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
9254 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9256 .dac_nids = alc883_dac_nids,
9257 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
9258 .dig_in_nid = ALC883_DIGIN_NID,
9259 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9260 .channel_mode = alc883_sixstack_modes,
9261 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
9262 .unsol_event = alc_automute_amp_unsol_event,
9263 .init_hook = alc888_6st_dell_init_hook,
5795b9e6 9264 },
a8848bd6
AS
9265 [ALC883_MITAC] = {
9266 .mixers = { alc883_mitac_mixer },
9267 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9268 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9269 .dac_nids = alc883_dac_nids,
a8848bd6
AS
9270 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9271 .channel_mode = alc883_3ST_2ch_modes,
9272 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
9273 .unsol_event = alc_automute_amp_unsol_event,
9274 .init_hook = alc883_mitac_init_hook,
a8848bd6 9275 },
fb97dc67
J
9276 [ALC883_FUJITSU_PI2515] = {
9277 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9278 .init_verbs = { alc883_init_verbs,
9279 alc883_2ch_fujitsu_pi2515_verbs},
9280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9281 .dac_nids = alc883_dac_nids,
9282 .dig_out_nid = ALC883_DIGOUT_NID,
9283 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9284 .channel_mode = alc883_3ST_2ch_modes,
9285 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f
TI
9286 .unsol_event = alc_automute_amp_unsol_event,
9287 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
fb97dc67 9288 },
ef8ef5fb
VP
9289 [ALC888_FUJITSU_XA3530] = {
9290 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9291 .init_verbs = { alc883_init_verbs,
9292 alc888_fujitsu_xa3530_verbs },
9293 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9294 .dac_nids = alc883_dac_nids,
9295 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9296 .adc_nids = alc883_adc_nids_rev,
9297 .capsrc_nids = alc883_capsrc_nids_rev,
9298 .dig_out_nid = ALC883_DIGOUT_NID,
9299 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9300 .channel_mode = alc888_4ST_8ch_intel_modes,
9301 .num_mux_defs =
9302 ARRAY_SIZE(alc888_2_capture_sources),
9303 .input_mux = alc888_2_capture_sources,
a9fd4f3f
TI
9304 .unsol_event = alc_automute_amp_unsol_event,
9305 .init_hook = alc888_fujitsu_xa3530_init_hook,
ef8ef5fb 9306 },
e2757d5e
KY
9307 [ALC888_LENOVO_SKY] = {
9308 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9309 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9310 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9311 .dac_nids = alc883_dac_nids,
9312 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
9313 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9314 .channel_mode = alc883_sixstack_modes,
9315 .need_dac_fix = 1,
9316 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f
TI
9317 .unsol_event = alc_automute_amp_unsol_event,
9318 .init_hook = alc888_lenovo_sky_init_hook,
e2757d5e
KY
9319 },
9320 [ALC888_ASUS_M90V] = {
9321 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9322 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9323 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9324 .dac_nids = alc883_dac_nids,
9325 .dig_out_nid = ALC883_DIGOUT_NID,
9326 .dig_in_nid = ALC883_DIGIN_NID,
9327 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9328 .channel_mode = alc883_3ST_6ch_modes,
9329 .need_dac_fix = 1,
9330 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9331 .unsol_event = alc883_mode2_unsol_event,
9332 .init_hook = alc883_mode2_inithook,
9333 },
9334 [ALC888_ASUS_EEE1601] = {
9335 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 9336 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
9337 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9338 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9339 .dac_nids = alc883_dac_nids,
9340 .dig_out_nid = ALC883_DIGOUT_NID,
9341 .dig_in_nid = ALC883_DIGIN_NID,
9342 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9343 .channel_mode = alc883_3ST_2ch_modes,
9344 .need_dac_fix = 1,
9345 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 9346 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
9347 .init_hook = alc883_eee1601_inithook,
9348 },
3ab90935
WF
9349 [ALC1200_ASUS_P5Q] = {
9350 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9351 .init_verbs = { alc883_init_verbs },
9352 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9353 .dac_nids = alc883_dac_nids,
9354 .dig_out_nid = ALC1200_DIGOUT_NID,
9355 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 9356 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
9357 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9358 .channel_mode = alc883_sixstack_modes,
9359 .input_mux = &alc883_capture_source,
9360 },
eb4c41d3
TS
9361 [ALC889A_MB31] = {
9362 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9363 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9364 alc880_gpio1_init_verbs },
9365 .adc_nids = alc883_adc_nids,
9366 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9367 .dac_nids = alc883_dac_nids,
9368 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9369 .channel_mode = alc889A_mb31_6ch_modes,
9370 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9371 .input_mux = &alc889A_mb31_capture_source,
9372 .dig_out_nid = ALC883_DIGOUT_NID,
9373 .unsol_event = alc889A_mb31_unsol_event,
9374 .init_hook = alc889A_mb31_automute,
9375 },
9c7f852e
TI
9376};
9377
9378
9379/*
9380 * BIOS auto configuration
9381 */
9382static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9383 hda_nid_t nid, int pin_type,
9384 int dac_idx)
9385{
9386 /* set as output */
9387 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
9388 int idx;
9389
f6c7e546 9390 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
9391 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9392 idx = 4;
9393 else
9394 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
9395 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9396
9397}
9398
9399static void alc883_auto_init_multi_out(struct hda_codec *codec)
9400{
9401 struct alc_spec *spec = codec->spec;
9402 int i;
9403
9404 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 9405 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 9406 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 9407 if (nid)
baba8ee9 9408 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 9409 i);
9c7f852e
TI
9410 }
9411}
9412
9413static void alc883_auto_init_hp_out(struct hda_codec *codec)
9414{
9415 struct alc_spec *spec = codec->spec;
9416 hda_nid_t pin;
9417
eb06ed8f 9418 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
9419 if (pin) /* connect to front */
9420 /* use dac 0 */
9421 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
9422 pin = spec->autocfg.speaker_pins[0];
9423 if (pin)
9424 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
9425}
9426
9427#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9428#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9429
9430static void alc883_auto_init_analog_input(struct hda_codec *codec)
9431{
9432 struct alc_spec *spec = codec->spec;
9433 int i;
9434
9435 for (i = 0; i < AUTO_PIN_LAST; i++) {
9436 hda_nid_t nid = spec->autocfg.input_pins[i];
9437 if (alc883_is_input_pin(nid)) {
23f0c048 9438 alc_set_input_pin(codec, nid, i);
e82c025b
TI
9439 if (nid != ALC883_PIN_CD_NID &&
9440 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9c7f852e
TI
9441 snd_hda_codec_write(codec, nid, 0,
9442 AC_VERB_SET_AMP_GAIN_MUTE,
9443 AMP_OUT_MUTE);
9444 }
9445 }
9446}
9447
f511b01c
TI
9448#define alc883_auto_init_input_src alc882_auto_init_input_src
9449
9c7f852e
TI
9450/* almost identical with ALC880 parser... */
9451static int alc883_parse_auto_config(struct hda_codec *codec)
9452{
9453 struct alc_spec *spec = codec->spec;
9454 int err = alc880_parse_auto_config(codec);
61b9b9b1
HRK
9455 struct auto_pin_cfg *cfg = &spec->autocfg;
9456 int i;
9c7f852e
TI
9457
9458 if (err < 0)
9459 return err;
776e184e
TI
9460 else if (!err)
9461 return 0; /* no config found */
9462
9463 err = alc_auto_add_mic_boost(codec);
9464 if (err < 0)
9465 return err;
9466
9467 /* hack - override the init verbs */
9468 spec->init_verbs[0] = alc883_auto_init_verbs;
776e184e 9469
61b9b9b1
HRK
9470 /* setup input_mux for ALC889 */
9471 if (codec->vendor_id == 0x10ec0889) {
9472 /* digital-mic input pin is excluded in alc880_auto_create..()
9473 * because it's under 0x18
9474 */
9475 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9476 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9477 struct hda_input_mux *imux = &spec->private_imux[0];
9478 for (i = 1; i < 3; i++)
9479 memcpy(&spec->private_imux[i],
9480 &spec->private_imux[0],
9481 sizeof(spec->private_imux[0]));
9482 imux->items[imux->num_items].label = "Int DMic";
9483 imux->items[imux->num_items].index = 0x0b;
9484 imux->num_items++;
9485 spec->num_mux_defs = 3;
9486 spec->input_mux = spec->private_imux;
9487 }
9488 }
9489
776e184e 9490 return 1; /* config found */
9c7f852e
TI
9491}
9492
9493/* additional initialization for auto-configuration model */
9494static void alc883_auto_init(struct hda_codec *codec)
9495{
f6c7e546 9496 struct alc_spec *spec = codec->spec;
9c7f852e
TI
9497 alc883_auto_init_multi_out(codec);
9498 alc883_auto_init_hp_out(codec);
9499 alc883_auto_init_analog_input(codec);
f511b01c 9500 alc883_auto_init_input_src(codec);
f6c7e546 9501 if (spec->unsol_event)
7fb0d78f 9502 alc_inithook(codec);
9c7f852e
TI
9503}
9504
9505static int patch_alc883(struct hda_codec *codec)
9506{
9507 struct alc_spec *spec;
9508 int err, board_config;
9509
9510 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9511 if (spec == NULL)
9512 return -ENOMEM;
9513
9514 codec->spec = spec;
9515
2c3bf9ab
TI
9516 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9517
f5fcc13c
TI
9518 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9519 alc883_models,
9520 alc883_cfg_tbl);
eb4c41d3
TS
9521 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9522 /* Pick up systems that don't supply PCI SSID */
9523 switch (codec->subsystem_id) {
9524 case 0x106b3600: /* Macbook 3.1 */
9525 board_config = ALC889A_MB31;
9526 break;
9527 default:
9528 printk(KERN_INFO
9529 "hda_codec: Unknown model for %s, trying "
9530 "auto-probe from BIOS...\n", codec->chip_name);
9531 board_config = ALC883_AUTO;
9532 }
9c7f852e
TI
9533 }
9534
9535 if (board_config == ALC883_AUTO) {
9536 /* automatic parse from the BIOS config */
9537 err = alc883_parse_auto_config(codec);
9538 if (err < 0) {
9539 alc_free(codec);
9540 return err;
f12ab1e0 9541 } else if (!err) {
9c7f852e
TI
9542 printk(KERN_INFO
9543 "hda_codec: Cannot set up configuration "
9544 "from BIOS. Using base mode...\n");
9545 board_config = ALC883_3ST_2ch_DIG;
9546 }
9547 }
9548
680cd536
KK
9549 err = snd_hda_attach_beep_device(codec, 0x1);
9550 if (err < 0) {
9551 alc_free(codec);
9552 return err;
9553 }
9554
9c7f852e
TI
9555 if (board_config != ALC883_AUTO)
9556 setup_preset(spec, &alc883_presets[board_config]);
9557
2f893286
KY
9558 switch (codec->vendor_id) {
9559 case 0x10ec0888:
61b9b9b1
HRK
9560 if (!spec->num_adc_nids) {
9561 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9562 spec->adc_nids = alc883_adc_nids;
9563 }
9564 if (!spec->capsrc_nids)
9565 spec->capsrc_nids = alc883_capsrc_nids;
9566 spec->capture_style = CAPT_MIX; /* matrix-style capture */
4a79ba34 9567 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
2f893286
KY
9568 break;
9569 case 0x10ec0889:
61b9b9b1
HRK
9570 if (!spec->num_adc_nids) {
9571 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9572 spec->adc_nids = alc889_adc_nids;
9573 }
9574 if (!spec->capsrc_nids)
9575 spec->capsrc_nids = alc889_capsrc_nids;
9576 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9577 capture */
2f893286
KY
9578 break;
9579 default:
61b9b9b1
HRK
9580 if (!spec->num_adc_nids) {
9581 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9582 spec->adc_nids = alc883_adc_nids;
9583 }
9584 if (!spec->capsrc_nids)
9585 spec->capsrc_nids = alc883_capsrc_nids;
9586 spec->capture_style = CAPT_MIX; /* matrix-style capture */
2f893286
KY
9587 break;
9588 }
9589
9c7f852e
TI
9590 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9591 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 9592 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e 9593
9c7f852e
TI
9594 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9595 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9596
f9e336f6
TI
9597 if (!spec->cap_mixer)
9598 set_capture_mixer(spec);
45bdd1c1 9599 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 9600
2134ea4f
TI
9601 spec->vmaster_nid = 0x0c;
9602
9c7f852e
TI
9603 codec->patch_ops = alc_patch_ops;
9604 if (board_config == ALC883_AUTO)
9605 spec->init_hook = alc883_auto_init;
f9423e7a 9606
cb53c626
TI
9607#ifdef CONFIG_SND_HDA_POWER_SAVE
9608 if (!spec->loopback.amplist)
9609 spec->loopback.amplist = alc883_loopbacks;
9610#endif
daead538 9611 codec->proc_widget_hook = print_realtek_coef;
9c7f852e
TI
9612
9613 return 0;
9614}
9615
9616/*
9617 * ALC262 support
9618 */
9619
9620#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9621#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9622
9623#define alc262_dac_nids alc260_dac_nids
9624#define alc262_adc_nids alc882_adc_nids
9625#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
9626#define alc262_capsrc_nids alc882_capsrc_nids
9627#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
9628
9629#define alc262_modes alc260_modes
9630#define alc262_capture_source alc882_capture_source
9631
4e555fe5
KY
9632static hda_nid_t alc262_dmic_adc_nids[1] = {
9633 /* ADC0 */
9634 0x09
9635};
9636
9637static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9638
9c7f852e
TI
9639static struct snd_kcontrol_new alc262_base_mixer[] = {
9640 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9641 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9647 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9648 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9650 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9651 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9654 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9655 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9656 { } /* end */
9657};
9658
ce875f07
TI
9659/* update HP, line and mono-out pins according to the master switch */
9660static void alc262_hp_master_update(struct hda_codec *codec)
9661{
9662 struct alc_spec *spec = codec->spec;
9663 int val = spec->master_sw;
9664
9665 /* HP & line-out */
9666 snd_hda_codec_write_cache(codec, 0x1b, 0,
9667 AC_VERB_SET_PIN_WIDGET_CONTROL,
9668 val ? PIN_HP : 0);
9669 snd_hda_codec_write_cache(codec, 0x15, 0,
9670 AC_VERB_SET_PIN_WIDGET_CONTROL,
9671 val ? PIN_HP : 0);
9672 /* mono (speaker) depending on the HP jack sense */
9673 val = val && !spec->jack_present;
9674 snd_hda_codec_write_cache(codec, 0x16, 0,
9675 AC_VERB_SET_PIN_WIDGET_CONTROL,
9676 val ? PIN_OUT : 0);
9677}
9678
9679static void alc262_hp_bpc_automute(struct hda_codec *codec)
9680{
9681 struct alc_spec *spec = codec->spec;
9682 unsigned int presence;
9683 presence = snd_hda_codec_read(codec, 0x1b, 0,
9684 AC_VERB_GET_PIN_SENSE, 0);
9685 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9686 alc262_hp_master_update(codec);
9687}
9688
9689static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9690{
9691 if ((res >> 26) != ALC880_HP_EVENT)
9692 return;
9693 alc262_hp_bpc_automute(codec);
9694}
9695
9696static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9697{
9698 struct alc_spec *spec = codec->spec;
9699 unsigned int presence;
9700 presence = snd_hda_codec_read(codec, 0x15, 0,
9701 AC_VERB_GET_PIN_SENSE, 0);
9702 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9703 alc262_hp_master_update(codec);
9704}
9705
9706static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9707 unsigned int res)
9708{
9709 if ((res >> 26) != ALC880_HP_EVENT)
9710 return;
9711 alc262_hp_wildwest_automute(codec);
9712}
9713
b72519b5 9714#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
9715
9716static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9717 struct snd_ctl_elem_value *ucontrol)
9718{
9719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9720 struct alc_spec *spec = codec->spec;
9721 int val = !!*ucontrol->value.integer.value;
9722
9723 if (val == spec->master_sw)
9724 return 0;
9725 spec->master_sw = val;
9726 alc262_hp_master_update(codec);
9727 return 1;
9728}
9729
b72519b5
TI
9730#define ALC262_HP_MASTER_SWITCH \
9731 { \
9732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9733 .name = "Master Playback Switch", \
9734 .info = snd_ctl_boolean_mono_info, \
9735 .get = alc262_hp_master_sw_get, \
9736 .put = alc262_hp_master_sw_put, \
9737 }
9738
9c7f852e 9739static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 9740 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
9741 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9742 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9744 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9745 HDA_OUTPUT),
9746 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9747 HDA_OUTPUT),
9c7f852e
TI
9748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9750 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9751 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9752 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9753 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9754 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9755 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
9758 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9759 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9760 { } /* end */
9761};
9762
cd7509a4 9763static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 9764 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
9765 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9766 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9769 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9770 HDA_OUTPUT),
9771 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9772 HDA_OUTPUT),
cd7509a4
KY
9773 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9775 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9776 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9777 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9778 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9779 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
9780 { } /* end */
9781};
9782
9783static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9784 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9785 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9786 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9787 { } /* end */
9788};
9789
66d2a9d6 9790/* mute/unmute internal speaker according to the hp jack and mute state */
a9fd4f3f 9791static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
66d2a9d6
KY
9792{
9793 struct alc_spec *spec = codec->spec;
66d2a9d6 9794
a9fd4f3f
TI
9795 spec->autocfg.hp_pins[0] = 0x15;
9796 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9797 alc_automute_amp(codec);
66d2a9d6
KY
9798}
9799
66d2a9d6 9800static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9801 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9802 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9803 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9807 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9808 { } /* end */
9809};
9810
9811static struct hda_verb alc262_hp_t5735_verbs[] = {
9812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9813 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9814
9815 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9816 { }
9817};
9818
8c427226 9819static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9820 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9822 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9823 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9824 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9825 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9826 { } /* end */
9827};
9828
9829static struct hda_verb alc262_hp_rp5700_verbs[] = {
9830 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9832 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9833 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9834 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9835 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9836 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9838 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9840 {}
9841};
9842
9843static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9844 .num_items = 1,
9845 .items = {
9846 { "Line", 0x1 },
9847 },
9848};
9849
42171c17
TI
9850/* bind hp and internal speaker mute (with plug check) as master switch */
9851static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 9852{
42171c17
TI
9853 struct alc_spec *spec = codec->spec;
9854 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9855 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9856 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9857 unsigned int mute;
0724ea2a 9858
42171c17
TI
9859 /* HP */
9860 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9861 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9862 HDA_AMP_MUTE, mute);
9863 /* mute internal speaker per jack sense */
9864 if (spec->jack_present)
9865 mute = HDA_AMP_MUTE;
9866 if (line_nid)
9867 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9868 HDA_AMP_MUTE, mute);
9869 if (speaker_nid && speaker_nid != line_nid)
9870 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 9871 HDA_AMP_MUTE, mute);
42171c17
TI
9872}
9873
9874#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9875
9876static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9877 struct snd_ctl_elem_value *ucontrol)
9878{
9879 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9880 struct alc_spec *spec = codec->spec;
9881 int val = !!*ucontrol->value.integer.value;
9882
9883 if (val == spec->master_sw)
9884 return 0;
9885 spec->master_sw = val;
9886 alc262_hippo_master_update(codec);
9887 return 1;
9888}
9889
9890#define ALC262_HIPPO_MASTER_SWITCH \
9891 { \
9892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9893 .name = "Master Playback Switch", \
9894 .info = snd_ctl_boolean_mono_info, \
9895 .get = alc262_hippo_master_sw_get, \
9896 .put = alc262_hippo_master_sw_put, \
0724ea2a 9897 }
42171c17
TI
9898
9899static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9900 ALC262_HIPPO_MASTER_SWITCH,
9901 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9902 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9903 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9904 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9905 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9906 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9908 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9909 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9910 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9911 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9913 { } /* end */
9914};
9915
9916static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9917 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9918 ALC262_HIPPO_MASTER_SWITCH,
9919 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9920 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9921 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9922 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9923 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9925 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9926 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9927 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9928 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9929 { } /* end */
9930};
9931
9932/* mute/unmute internal speaker according to the hp jack and mute state */
9933static void alc262_hippo_automute(struct hda_codec *codec)
9934{
9935 struct alc_spec *spec = codec->spec;
9936 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9937 unsigned int present;
9938
9939 /* need to execute and sync at first */
9940 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9941 present = snd_hda_codec_read(codec, hp_nid, 0,
9942 AC_VERB_GET_PIN_SENSE, 0);
9943 spec->jack_present = (present & 0x80000000) != 0;
9944 alc262_hippo_master_update(codec);
0724ea2a 9945}
5b31954e 9946
42171c17
TI
9947static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9948{
9949 if ((res >> 26) != ALC880_HP_EVENT)
9950 return;
9951 alc262_hippo_automute(codec);
9952}
9953
9954static void alc262_hippo_init_hook(struct hda_codec *codec)
9955{
9956 struct alc_spec *spec = codec->spec;
9957
9958 spec->autocfg.hp_pins[0] = 0x15;
9959 spec->autocfg.speaker_pins[0] = 0x14;
9960 alc262_hippo_automute(codec);
9961}
9962
9963static void alc262_hippo1_init_hook(struct hda_codec *codec)
9964{
9965 struct alc_spec *spec = codec->spec;
9966
9967 spec->autocfg.hp_pins[0] = 0x1b;
9968 spec->autocfg.speaker_pins[0] = 0x14;
9969 alc262_hippo_automute(codec);
9970}
9971
9972
272a527c 9973static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 9974 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 9975 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
9976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9978 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9979 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9980 { } /* end */
9981};
9982
83c34218 9983static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
9984 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9985 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
9986 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9989 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9990 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9991 { } /* end */
9992};
272a527c 9993
ba340e82
TV
9994static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9995 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9996 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9997 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9998 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10003 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10005 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10006 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10007 { } /* end */
10008};
10009
10010static struct hda_verb alc262_tyan_verbs[] = {
10011 /* Headphone automute */
10012 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10013 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10015
10016 /* P11 AUX_IN, white 4-pin connector */
10017 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10018 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10019 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10020 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10021
10022 {}
10023};
10024
10025/* unsolicited event for HP jack sensing */
a9fd4f3f 10026static void alc262_tyan_init_hook(struct hda_codec *codec)
ba340e82 10027{
a9fd4f3f 10028 struct alc_spec *spec = codec->spec;
ba340e82 10029
a9fd4f3f
TI
10030 spec->autocfg.hp_pins[0] = 0x1b;
10031 spec->autocfg.speaker_pins[0] = 0x15;
10032 alc_automute_amp(codec);
ba340e82
TV
10033}
10034
ba340e82 10035
9c7f852e
TI
10036#define alc262_capture_mixer alc882_capture_mixer
10037#define alc262_capture_alt_mixer alc882_capture_alt_mixer
10038
10039/*
10040 * generic initialization of ADC, input mixers and output mixers
10041 */
10042static struct hda_verb alc262_init_verbs[] = {
10043 /*
10044 * Unmute ADC0-2 and set the default input to mic-in
10045 */
10046 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10048 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10049 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10050 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10051 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10052
cb53c626 10053 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10054 * mixer widget
f12ab1e0
TI
10055 * Note: PASD motherboards uses the Line In 2 as the input for
10056 * front panel mic (mic 2)
9c7f852e
TI
10057 */
10058 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
10064
10065 /*
df694daa
KY
10066 * Set up output mixers (0x0c - 0x0e)
10067 */
10068 /* set vol=0 to output mixers */
10069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10072 /* set up input amps for analog loopback */
10073 /* Amp Indices: DAC = 0, mixer = 1 */
10074 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10076 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10078 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10080
10081 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10082 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10083 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10084 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10086 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10087
10088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10092 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 10093
df694daa
KY
10094 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 10096
df694daa
KY
10097 /* FIXME: use matrix-type input source selection */
10098 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10099 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10100 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10101 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10102 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10103 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10104 /* Input mixer2 */
10105 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10106 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10107 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10109 /* Input mixer3 */
10110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 10113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
10114
10115 { }
10116};
1da177e4 10117
4e555fe5
KY
10118static struct hda_verb alc262_eapd_verbs[] = {
10119 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10120 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10121 { }
10122};
10123
ccc656ce
KY
10124static struct hda_verb alc262_hippo_unsol_verbs[] = {
10125 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10127 {}
10128};
10129
10130static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10131 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10132 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10133 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10134
10135 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10137 {}
10138};
10139
272a527c
KY
10140static struct hda_verb alc262_sony_unsol_verbs[] = {
10141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10142 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10144
10145 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 10147 {}
272a527c
KY
10148};
10149
4e555fe5
KY
10150static struct hda_input_mux alc262_dmic_capture_source = {
10151 .num_items = 2,
10152 .items = {
10153 { "Int DMic", 0x9 },
10154 { "Mic", 0x0 },
10155 },
10156};
10157
10158static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10159 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10160 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10161 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
10164 { } /* end */
10165};
10166
10167static struct hda_verb alc262_toshiba_s06_verbs[] = {
10168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10171 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10172 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10173 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10174 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10175 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10176 {}
10177};
10178
10179static void alc262_dmic_automute(struct hda_codec *codec)
10180{
10181 unsigned int present;
10182
10183 present = snd_hda_codec_read(codec, 0x18, 0,
10184 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10185 snd_hda_codec_write(codec, 0x22, 0,
10186 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10187}
10188
4e555fe5
KY
10189
10190/* unsolicited event for HP jack sensing */
10191static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10192 unsigned int res)
10193{
4e555fe5
KY
10194 if ((res >> 26) == ALC880_MIC_EVENT)
10195 alc262_dmic_automute(codec);
a9fd4f3f
TI
10196 else
10197 alc_sku_unsol_event(codec, res);
4e555fe5
KY
10198}
10199
10200static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10201{
a9fd4f3f
TI
10202 struct alc_spec *spec = codec->spec;
10203
10204 spec->autocfg.hp_pins[0] = 0x15;
10205 spec->autocfg.speaker_pins[0] = 0x14;
10206 alc_automute_pin(codec);
4e555fe5
KY
10207 alc262_dmic_automute(codec);
10208}
10209
e8f9ae2a
PT
10210/*
10211 * nec model
10212 * 0x15 = headphone
10213 * 0x16 = internal speaker
10214 * 0x18 = external mic
10215 */
10216
10217static struct snd_kcontrol_new alc262_nec_mixer[] = {
10218 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10219 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10220
10221 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10223 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10224
10225 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10227 { } /* end */
10228};
10229
10230static struct hda_verb alc262_nec_verbs[] = {
10231 /* Unmute Speaker */
10232 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10233
10234 /* Headphone */
10235 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10237
10238 /* External mic to headphone */
10239 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10240 /* External mic to speaker */
10241 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10242 {}
10243};
10244
834be88d
TI
10245/*
10246 * fujitsu model
5d9fab2d
TV
10247 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10248 * 0x1b = port replicator headphone out
834be88d
TI
10249 */
10250
10251#define ALC_HP_EVENT 0x37
10252
10253static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10254 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
10256 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10257 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
10258 {}
10259};
10260
0e31daf7
J
10261static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10262 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10263 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10264 {}
10265};
10266
834be88d 10267static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 10268 .num_items = 3,
834be88d
TI
10269 .items = {
10270 { "Mic", 0x0 },
39d3ed38 10271 { "Int Mic", 0x1 },
834be88d
TI
10272 { "CD", 0x4 },
10273 },
10274};
10275
9c7f852e
TI
10276static struct hda_input_mux alc262_HP_capture_source = {
10277 .num_items = 5,
10278 .items = {
10279 { "Mic", 0x0 },
accbe498 10280 { "Front Mic", 0x1 },
9c7f852e
TI
10281 { "Line", 0x2 },
10282 { "CD", 0x4 },
10283 { "AUX IN", 0x6 },
10284 },
10285};
10286
accbe498 10287static struct hda_input_mux alc262_HP_D7000_capture_source = {
10288 .num_items = 4,
10289 .items = {
10290 { "Mic", 0x0 },
10291 { "Front Mic", 0x2 },
10292 { "Line", 0x1 },
10293 { "CD", 0x4 },
10294 },
10295};
10296
ebc7a406 10297/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
10298static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10299{
10300 struct alc_spec *spec = codec->spec;
10301 unsigned int mute;
10302
f12ab1e0 10303 if (force || !spec->sense_updated) {
ebc7a406 10304 unsigned int present;
834be88d
TI
10305 /* need to execute and sync at first */
10306 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
10307 /* check laptop HP jack */
10308 present = snd_hda_codec_read(codec, 0x14, 0,
10309 AC_VERB_GET_PIN_SENSE, 0);
10310 /* need to execute and sync at first */
10311 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10312 /* check docking HP jack */
10313 present |= snd_hda_codec_read(codec, 0x1b, 0,
10314 AC_VERB_GET_PIN_SENSE, 0);
10315 if (present & AC_PINSENSE_PRESENCE)
10316 spec->jack_present = 1;
10317 else
10318 spec->jack_present = 0;
834be88d
TI
10319 spec->sense_updated = 1;
10320 }
ebc7a406
TI
10321 /* unmute internal speaker only if both HPs are unplugged and
10322 * master switch is on
10323 */
10324 if (spec->jack_present)
10325 mute = HDA_AMP_MUTE;
10326 else
834be88d 10327 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
10328 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10329 HDA_AMP_MUTE, mute);
834be88d
TI
10330}
10331
10332/* unsolicited event for HP jack sensing */
10333static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10334 unsigned int res)
10335{
10336 if ((res >> 26) != ALC_HP_EVENT)
10337 return;
10338 alc262_fujitsu_automute(codec, 1);
10339}
10340
ebc7a406
TI
10341static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10342{
10343 alc262_fujitsu_automute(codec, 1);
10344}
10345
834be88d 10346/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
10347static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10348 .ops = &snd_hda_bind_vol,
10349 .values = {
10350 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10351 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10352 0
10353 },
10354};
834be88d 10355
0e31daf7
J
10356/* mute/unmute internal speaker according to the hp jack and mute state */
10357static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10358{
10359 struct alc_spec *spec = codec->spec;
10360 unsigned int mute;
10361
10362 if (force || !spec->sense_updated) {
10363 unsigned int present_int_hp;
10364 /* need to execute and sync at first */
10365 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10366 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10367 AC_VERB_GET_PIN_SENSE, 0);
10368 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10369 spec->sense_updated = 1;
10370 }
10371 if (spec->jack_present) {
10372 /* mute internal speaker */
10373 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10374 HDA_AMP_MUTE, HDA_AMP_MUTE);
10375 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10376 HDA_AMP_MUTE, HDA_AMP_MUTE);
10377 } else {
10378 /* unmute internal speaker if necessary */
10379 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10380 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10381 HDA_AMP_MUTE, mute);
10382 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10383 HDA_AMP_MUTE, mute);
10384 }
10385}
10386
10387/* unsolicited event for HP jack sensing */
10388static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10389 unsigned int res)
10390{
10391 if ((res >> 26) != ALC_HP_EVENT)
10392 return;
10393 alc262_lenovo_3000_automute(codec, 1);
10394}
10395
834be88d
TI
10396/* bind hp and internal speaker mute (with plug check) */
10397static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10398 struct snd_ctl_elem_value *ucontrol)
10399{
10400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10401 long *valp = ucontrol->value.integer.value;
10402 int change;
10403
5d9fab2d
TV
10404 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10405 HDA_AMP_MUTE,
10406 valp ? 0 : HDA_AMP_MUTE);
10407 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10408 HDA_AMP_MUTE,
10409 valp ? 0 : HDA_AMP_MUTE);
10410
82beb8fd
TI
10411 if (change)
10412 alc262_fujitsu_automute(codec, 0);
834be88d
TI
10413 return change;
10414}
10415
10416static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 10417 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
10418 {
10419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10420 .name = "Master Playback Switch",
10421 .info = snd_hda_mixer_amp_switch_info,
10422 .get = snd_hda_mixer_amp_switch_get,
10423 .put = alc262_fujitsu_master_sw_put,
10424 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10425 },
10426 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10427 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10428 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10430 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
10431 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10432 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10433 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
10434 { } /* end */
10435};
10436
0e31daf7
J
10437/* bind hp and internal speaker mute (with plug check) */
10438static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10439 struct snd_ctl_elem_value *ucontrol)
10440{
10441 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10442 long *valp = ucontrol->value.integer.value;
10443 int change;
10444
10445 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10446 HDA_AMP_MUTE,
10447 valp ? 0 : HDA_AMP_MUTE);
10448
10449 if (change)
10450 alc262_lenovo_3000_automute(codec, 0);
10451 return change;
10452}
10453
10454static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10455 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10456 {
10457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10458 .name = "Master Playback Switch",
10459 .info = snd_hda_mixer_amp_switch_info,
10460 .get = snd_hda_mixer_amp_switch_get,
10461 .put = alc262_lenovo_3000_master_sw_put,
10462 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10463 },
10464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10466 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10469 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10470 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10471 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10472 { } /* end */
10473};
10474
9f99a638
HM
10475static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10476 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 10477 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
10478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10480 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10481 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10483 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10484 { } /* end */
10485};
10486
304dcaac
TI
10487/* additional init verbs for Benq laptops */
10488static struct hda_verb alc262_EAPD_verbs[] = {
10489 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10490 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10491 {}
10492};
10493
83c34218
KY
10494static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10495 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10497
10498 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10499 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10500 {}
10501};
10502
f651b50b
TD
10503/* Samsung Q1 Ultra Vista model setup */
10504static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
10505 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10506 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
10507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10509 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 10510 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
10511 { } /* end */
10512};
10513
10514static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
10515 /* output mixer */
10516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10519 /* speaker */
10520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10521 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10524 /* HP */
f651b50b 10525 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
10526 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10529 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10530 /* internal mic */
10531 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10533 /* ADC, choose mic */
10534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10535 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10536 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10537 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10538 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10539 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
10544 {}
10545};
10546
f651b50b
TD
10547/* mute/unmute internal speaker according to the hp jack and mute state */
10548static void alc262_ultra_automute(struct hda_codec *codec)
10549{
10550 struct alc_spec *spec = codec->spec;
10551 unsigned int mute;
f651b50b 10552
bb9f76cd
TI
10553 mute = 0;
10554 /* auto-mute only when HP is used as HP */
10555 if (!spec->cur_mux[0]) {
10556 unsigned int present;
10557 /* need to execute and sync at first */
10558 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10559 present = snd_hda_codec_read(codec, 0x15, 0,
10560 AC_VERB_GET_PIN_SENSE, 0);
10561 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10562 if (spec->jack_present)
10563 mute = HDA_AMP_MUTE;
f651b50b 10564 }
bb9f76cd
TI
10565 /* mute/unmute internal speaker */
10566 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10567 HDA_AMP_MUTE, mute);
10568 /* mute/unmute HP */
10569 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10570 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
10571}
10572
10573/* unsolicited event for HP jack sensing */
10574static void alc262_ultra_unsol_event(struct hda_codec *codec,
10575 unsigned int res)
10576{
10577 if ((res >> 26) != ALC880_HP_EVENT)
10578 return;
10579 alc262_ultra_automute(codec);
10580}
10581
bb9f76cd
TI
10582static struct hda_input_mux alc262_ultra_capture_source = {
10583 .num_items = 2,
10584 .items = {
10585 { "Mic", 0x1 },
10586 { "Headphone", 0x7 },
10587 },
10588};
10589
10590static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10591 struct snd_ctl_elem_value *ucontrol)
10592{
10593 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10594 struct alc_spec *spec = codec->spec;
10595 int ret;
10596
54cbc9ab 10597 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
10598 if (!ret)
10599 return 0;
10600 /* reprogram the HP pin as mic or HP according to the input source */
10601 snd_hda_codec_write_cache(codec, 0x15, 0,
10602 AC_VERB_SET_PIN_WIDGET_CONTROL,
10603 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10604 alc262_ultra_automute(codec); /* mute/unmute HP */
10605 return ret;
10606}
10607
10608static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10609 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10610 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10611 {
10612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10613 .name = "Capture Source",
54cbc9ab
TI
10614 .info = alc_mux_enum_info,
10615 .get = alc_mux_enum_get,
bb9f76cd
TI
10616 .put = alc262_ultra_mux_enum_put,
10617 },
10618 { } /* end */
10619};
10620
df694daa 10621/* add playback controls from the parsed DAC table */
f12ab1e0
TI
10622static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10623 const struct auto_pin_cfg *cfg)
df694daa
KY
10624{
10625 hda_nid_t nid;
10626 int err;
10627
10628 spec->multiout.num_dacs = 1; /* only use one dac */
10629 spec->multiout.dac_nids = spec->private_dac_nids;
10630 spec->multiout.dac_nids[0] = 2;
10631
10632 nid = cfg->line_out_pins[0];
10633 if (nid) {
f12ab1e0
TI
10634 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10635 "Front Playback Volume",
10636 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10637 if (err < 0)
df694daa 10638 return err;
f12ab1e0
TI
10639 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10640 "Front Playback Switch",
10641 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10642 if (err < 0)
df694daa
KY
10643 return err;
10644 }
10645
82bc955f 10646 nid = cfg->speaker_pins[0];
df694daa
KY
10647 if (nid) {
10648 if (nid == 0x16) {
f12ab1e0
TI
10649 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10650 "Speaker Playback Volume",
10651 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10652 HDA_OUTPUT));
10653 if (err < 0)
df694daa 10654 return err;
f12ab1e0
TI
10655 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10656 "Speaker Playback Switch",
10657 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10658 HDA_OUTPUT));
10659 if (err < 0)
df694daa
KY
10660 return err;
10661 } else {
f12ab1e0
TI
10662 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10663 "Speaker Playback Switch",
10664 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10665 HDA_OUTPUT));
10666 if (err < 0)
df694daa
KY
10667 return err;
10668 }
10669 }
eb06ed8f 10670 nid = cfg->hp_pins[0];
df694daa
KY
10671 if (nid) {
10672 /* spec->multiout.hp_nid = 2; */
10673 if (nid == 0x16) {
f12ab1e0
TI
10674 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10675 "Headphone Playback Volume",
10676 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10677 HDA_OUTPUT));
10678 if (err < 0)
df694daa 10679 return err;
f12ab1e0
TI
10680 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10681 "Headphone Playback Switch",
10682 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10683 HDA_OUTPUT));
10684 if (err < 0)
df694daa
KY
10685 return err;
10686 } else {
f12ab1e0
TI
10687 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10688 "Headphone Playback Switch",
10689 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10690 HDA_OUTPUT));
10691 if (err < 0)
df694daa
KY
10692 return err;
10693 }
10694 }
f12ab1e0 10695 return 0;
df694daa
KY
10696}
10697
10698/* identical with ALC880 */
f12ab1e0
TI
10699#define alc262_auto_create_analog_input_ctls \
10700 alc880_auto_create_analog_input_ctls
df694daa
KY
10701
10702/*
10703 * generic initialization of ADC, input mixers and output mixers
10704 */
10705static struct hda_verb alc262_volume_init_verbs[] = {
10706 /*
10707 * Unmute ADC0-2 and set the default input to mic-in
10708 */
10709 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10711 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10712 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10713 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10715
cb53c626 10716 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10717 * mixer widget
f12ab1e0
TI
10718 * Note: PASD motherboards uses the Line In 2 as the input for
10719 * front panel mic (mic 2)
df694daa
KY
10720 */
10721 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10727
10728 /*
10729 * Set up output mixers (0x0c - 0x0f)
10730 */
10731 /* set vol=0 to output mixers */
10732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10733 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10735
df694daa
KY
10736 /* set up input amps for analog loopback */
10737 /* Amp Indices: DAC = 0, mixer = 1 */
10738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10743 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10744
10745 /* FIXME: use matrix-type input source selection */
10746 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10747 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10749 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10750 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10751 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10752 /* Input mixer2 */
10753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10755 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10756 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10757 /* Input mixer3 */
10758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10762
10763 { }
10764};
10765
9c7f852e
TI
10766static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10767 /*
10768 * Unmute ADC0-2 and set the default input to mic-in
10769 */
10770 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10771 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10772 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10773 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10774 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10775 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10776
cb53c626 10777 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10778 * mixer widget
f12ab1e0
TI
10779 * Note: PASD motherboards uses the Line In 2 as the input for
10780 * front panel mic (mic 2)
9c7f852e
TI
10781 */
10782 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10783 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10784 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10785 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10786 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10787 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10788 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10790
9c7f852e
TI
10791 /*
10792 * Set up output mixers (0x0c - 0x0e)
10793 */
10794 /* set vol=0 to output mixers */
10795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10798
10799 /* set up input amps for analog loopback */
10800 /* Amp Indices: DAC = 0, mixer = 1 */
10801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10804 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10805 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10807
ce875f07 10808 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10810 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10811
10812 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10814
10815 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10816 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10817
10818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10820 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10822 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10823
0e4835c1 10824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
10825 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10826 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 10827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
10828 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10829 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10830
10831
10832 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
10833 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10834 /* Input mixer1: only unmute Mic */
9c7f852e 10835 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
10836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10840 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10841 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10842 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10843 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
10844 /* Input mixer2 */
10845 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
10846 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10847 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10848 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10849 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10850 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10851 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10852 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10853 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
10854 /* Input mixer3 */
10855 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
10856 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10863 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 10864
ce875f07
TI
10865 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10866
9c7f852e
TI
10867 { }
10868};
10869
cd7509a4
KY
10870static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10871 /*
10872 * Unmute ADC0-2 and set the default input to mic-in
10873 */
10874 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10876 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10877 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10878 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10879 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10880
cb53c626 10881 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10882 * mixer widget
10883 * Note: PASD motherboards uses the Line In 2 as the input for front
10884 * panel mic (mic 2)
10885 */
10886 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10887 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10888 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10889 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10890 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10895 /*
10896 * Set up output mixers (0x0c - 0x0e)
10897 */
10898 /* set vol=0 to output mixers */
10899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10900 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10901 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10902
10903 /* set up input amps for analog loopback */
10904 /* Amp Indices: DAC = 0, mixer = 1 */
10905 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10906 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10909 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10911
10912
10913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10914 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10915 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10917 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10919 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10920
10921 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10923
10924 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10925 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10926
10927 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10929 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10930 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10931 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10932 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10933
10934 /* FIXME: use matrix-type input source selection */
10935 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10936 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10937 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10938 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10940 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10941 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10942 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10943 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10944 /* Input mixer2 */
10945 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10950 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10951 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10952 /* Input mixer3 */
10953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10957 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10958 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10959 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10960
ce875f07
TI
10961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10962
cd7509a4
KY
10963 { }
10964};
10965
9f99a638
HM
10966static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10967
10968 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10969 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10970 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10971
10972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10973 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10974 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10975 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10976
10977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10978 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10979 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10980 {}
10981};
10982
10983
cb53c626
TI
10984#ifdef CONFIG_SND_HDA_POWER_SAVE
10985#define alc262_loopbacks alc880_loopbacks
10986#endif
10987
df694daa
KY
10988/* pcm configuration: identiacal with ALC880 */
10989#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10990#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10991#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10992#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10993
10994/*
10995 * BIOS auto configuration
10996 */
10997static int alc262_parse_auto_config(struct hda_codec *codec)
10998{
10999 struct alc_spec *spec = codec->spec;
11000 int err;
11001 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11002
f12ab1e0
TI
11003 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11004 alc262_ignore);
11005 if (err < 0)
df694daa 11006 return err;
e64f14f4 11007 if (!spec->autocfg.line_outs) {
0852d7a6 11008 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
11009 spec->multiout.max_channels = 2;
11010 spec->no_analog = 1;
11011 goto dig_only;
11012 }
df694daa 11013 return 0; /* can't find valid BIOS pin config */
e64f14f4 11014 }
f12ab1e0
TI
11015 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11016 if (err < 0)
11017 return err;
11018 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
11019 if (err < 0)
df694daa
KY
11020 return err;
11021
11022 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11023
e64f14f4 11024 dig_only:
0852d7a6 11025 if (spec->autocfg.dig_outs) {
df694daa 11026 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 11027 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 11028 }
df694daa
KY
11029 if (spec->autocfg.dig_in_pin)
11030 spec->dig_in_nid = ALC262_DIGIN_NID;
11031
603c4019 11032 if (spec->kctls.list)
d88897ea 11033 add_mixer(spec, spec->kctls.list);
df694daa 11034
d88897ea 11035 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 11036 spec->num_mux_defs = 1;
61b9b9b1 11037 spec->input_mux = &spec->private_imux[0];
df694daa 11038
776e184e
TI
11039 err = alc_auto_add_mic_boost(codec);
11040 if (err < 0)
11041 return err;
11042
4a79ba34
TI
11043 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11044
df694daa
KY
11045 return 1;
11046}
11047
11048#define alc262_auto_init_multi_out alc882_auto_init_multi_out
11049#define alc262_auto_init_hp_out alc882_auto_init_hp_out
11050#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 11051#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
11052
11053
11054/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 11055static void alc262_auto_init(struct hda_codec *codec)
df694daa 11056{
f6c7e546 11057 struct alc_spec *spec = codec->spec;
df694daa
KY
11058 alc262_auto_init_multi_out(codec);
11059 alc262_auto_init_hp_out(codec);
11060 alc262_auto_init_analog_input(codec);
f511b01c 11061 alc262_auto_init_input_src(codec);
f6c7e546 11062 if (spec->unsol_event)
7fb0d78f 11063 alc_inithook(codec);
df694daa
KY
11064}
11065
11066/*
11067 * configuration and preset
11068 */
f5fcc13c
TI
11069static const char *alc262_models[ALC262_MODEL_LAST] = {
11070 [ALC262_BASIC] = "basic",
11071 [ALC262_HIPPO] = "hippo",
11072 [ALC262_HIPPO_1] = "hippo_1",
11073 [ALC262_FUJITSU] = "fujitsu",
11074 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 11075 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 11076 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 11077 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 11078 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
11079 [ALC262_BENQ_T31] = "benq-t31",
11080 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 11081 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 11082 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 11083 [ALC262_ULTRA] = "ultra",
0e31daf7 11084 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 11085 [ALC262_NEC] = "nec",
ba340e82 11086 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
11087 [ALC262_AUTO] = "auto",
11088};
11089
11090static struct snd_pci_quirk alc262_cfg_tbl[] = {
11091 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 11092 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
11093 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11094 ALC262_HP_BPC),
11095 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11096 ALC262_HP_BPC),
53eff7e1
TI
11097 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11098 ALC262_HP_BPC),
cd7509a4 11099 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11100 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11101 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11102 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11103 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11104 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11105 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11106 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
11107 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11108 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11109 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
11110 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11111 ALC262_HP_TC_T5735),
8c427226 11112 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 11113 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 11114 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 11115 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 11116 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
f872a919
TI
11117 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11118 ALC262_SONY_ASSAMD),
36ca6e13 11119 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 11120 ALC262_TOSHIBA_RX1),
80ffe869 11121 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 11122 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 11123 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 11124 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
11125 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11126 ALC262_ULTRA),
3e420e78 11127 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 11128 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
11129 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11130 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11131 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
11132 {}
11133};
11134
11135static struct alc_config_preset alc262_presets[] = {
11136 [ALC262_BASIC] = {
11137 .mixers = { alc262_base_mixer },
11138 .init_verbs = { alc262_init_verbs },
11139 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11140 .dac_nids = alc262_dac_nids,
11141 .hp_nid = 0x03,
11142 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11143 .channel_mode = alc262_modes,
a3bcba38 11144 .input_mux = &alc262_capture_source,
df694daa 11145 },
ccc656ce 11146 [ALC262_HIPPO] = {
42171c17 11147 .mixers = { alc262_hippo_mixer },
ccc656ce
KY
11148 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
11149 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11150 .dac_nids = alc262_dac_nids,
11151 .hp_nid = 0x03,
11152 .dig_out_nid = ALC262_DIGOUT_NID,
11153 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11154 .channel_mode = alc262_modes,
11155 .input_mux = &alc262_capture_source,
11156 .unsol_event = alc262_hippo_unsol_event,
42171c17 11157 .init_hook = alc262_hippo_init_hook,
ccc656ce
KY
11158 },
11159 [ALC262_HIPPO_1] = {
11160 .mixers = { alc262_hippo1_mixer },
11161 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11162 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11163 .dac_nids = alc262_dac_nids,
11164 .hp_nid = 0x02,
11165 .dig_out_nid = ALC262_DIGOUT_NID,
11166 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11167 .channel_mode = alc262_modes,
11168 .input_mux = &alc262_capture_source,
42171c17
TI
11169 .unsol_event = alc262_hippo_unsol_event,
11170 .init_hook = alc262_hippo1_init_hook,
ccc656ce 11171 },
834be88d
TI
11172 [ALC262_FUJITSU] = {
11173 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
11174 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11175 alc262_fujitsu_unsol_verbs },
834be88d
TI
11176 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11177 .dac_nids = alc262_dac_nids,
11178 .hp_nid = 0x03,
11179 .dig_out_nid = ALC262_DIGOUT_NID,
11180 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11181 .channel_mode = alc262_modes,
11182 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 11183 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 11184 .init_hook = alc262_fujitsu_init_hook,
834be88d 11185 },
9c7f852e
TI
11186 [ALC262_HP_BPC] = {
11187 .mixers = { alc262_HP_BPC_mixer },
11188 .init_verbs = { alc262_HP_BPC_init_verbs },
11189 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11190 .dac_nids = alc262_dac_nids,
11191 .hp_nid = 0x03,
11192 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11193 .channel_mode = alc262_modes,
11194 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
11195 .unsol_event = alc262_hp_bpc_unsol_event,
11196 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 11197 },
cd7509a4
KY
11198 [ALC262_HP_BPC_D7000_WF] = {
11199 .mixers = { alc262_HP_BPC_WildWest_mixer },
11200 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11201 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11202 .dac_nids = alc262_dac_nids,
11203 .hp_nid = 0x03,
11204 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11205 .channel_mode = alc262_modes,
accbe498 11206 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11207 .unsol_event = alc262_hp_wildwest_unsol_event,
11208 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11209 },
cd7509a4
KY
11210 [ALC262_HP_BPC_D7000_WL] = {
11211 .mixers = { alc262_HP_BPC_WildWest_mixer,
11212 alc262_HP_BPC_WildWest_option_mixer },
11213 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11214 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11215 .dac_nids = alc262_dac_nids,
11216 .hp_nid = 0x03,
11217 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11218 .channel_mode = alc262_modes,
accbe498 11219 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11220 .unsol_event = alc262_hp_wildwest_unsol_event,
11221 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11222 },
66d2a9d6
KY
11223 [ALC262_HP_TC_T5735] = {
11224 .mixers = { alc262_hp_t5735_mixer },
11225 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11226 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11227 .dac_nids = alc262_dac_nids,
11228 .hp_nid = 0x03,
11229 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11230 .channel_mode = alc262_modes,
11231 .input_mux = &alc262_capture_source,
a9fd4f3f 11232 .unsol_event = alc_automute_amp_unsol_event,
66d2a9d6 11233 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
11234 },
11235 [ALC262_HP_RP5700] = {
11236 .mixers = { alc262_hp_rp5700_mixer },
11237 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11238 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11239 .dac_nids = alc262_dac_nids,
11240 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11241 .channel_mode = alc262_modes,
11242 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 11243 },
304dcaac
TI
11244 [ALC262_BENQ_ED8] = {
11245 .mixers = { alc262_base_mixer },
11246 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11247 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11248 .dac_nids = alc262_dac_nids,
11249 .hp_nid = 0x03,
11250 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11251 .channel_mode = alc262_modes,
11252 .input_mux = &alc262_capture_source,
f12ab1e0 11253 },
272a527c
KY
11254 [ALC262_SONY_ASSAMD] = {
11255 .mixers = { alc262_sony_mixer },
11256 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11257 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11258 .dac_nids = alc262_dac_nids,
11259 .hp_nid = 0x02,
11260 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11261 .channel_mode = alc262_modes,
11262 .input_mux = &alc262_capture_source,
11263 .unsol_event = alc262_hippo_unsol_event,
42171c17 11264 .init_hook = alc262_hippo_init_hook,
83c34218
KY
11265 },
11266 [ALC262_BENQ_T31] = {
11267 .mixers = { alc262_benq_t31_mixer },
11268 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11269 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11270 .dac_nids = alc262_dac_nids,
11271 .hp_nid = 0x03,
11272 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11273 .channel_mode = alc262_modes,
11274 .input_mux = &alc262_capture_source,
11275 .unsol_event = alc262_hippo_unsol_event,
42171c17 11276 .init_hook = alc262_hippo_init_hook,
ea1fb29a 11277 },
f651b50b 11278 [ALC262_ULTRA] = {
f9e336f6
TI
11279 .mixers = { alc262_ultra_mixer },
11280 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 11281 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
11282 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11283 .dac_nids = alc262_dac_nids,
f651b50b
TD
11284 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11285 .channel_mode = alc262_modes,
11286 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
11287 .adc_nids = alc262_adc_nids, /* ADC0 */
11288 .capsrc_nids = alc262_capsrc_nids,
11289 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
11290 .unsol_event = alc262_ultra_unsol_event,
11291 .init_hook = alc262_ultra_automute,
11292 },
0e31daf7
J
11293 [ALC262_LENOVO_3000] = {
11294 .mixers = { alc262_lenovo_3000_mixer },
11295 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11296 alc262_lenovo_3000_unsol_verbs },
11297 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11298 .dac_nids = alc262_dac_nids,
11299 .hp_nid = 0x03,
11300 .dig_out_nid = ALC262_DIGOUT_NID,
11301 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11302 .channel_mode = alc262_modes,
11303 .input_mux = &alc262_fujitsu_capture_source,
11304 .unsol_event = alc262_lenovo_3000_unsol_event,
11305 },
e8f9ae2a
PT
11306 [ALC262_NEC] = {
11307 .mixers = { alc262_nec_mixer },
11308 .init_verbs = { alc262_nec_verbs },
11309 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11310 .dac_nids = alc262_dac_nids,
11311 .hp_nid = 0x03,
11312 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11313 .channel_mode = alc262_modes,
11314 .input_mux = &alc262_capture_source,
11315 },
4e555fe5
KY
11316 [ALC262_TOSHIBA_S06] = {
11317 .mixers = { alc262_toshiba_s06_mixer },
11318 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11319 alc262_eapd_verbs },
11320 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11321 .capsrc_nids = alc262_dmic_capsrc_nids,
11322 .dac_nids = alc262_dac_nids,
11323 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11324 .dig_out_nid = ALC262_DIGOUT_NID,
11325 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11326 .channel_mode = alc262_modes,
11327 .input_mux = &alc262_dmic_capture_source,
11328 .unsol_event = alc262_toshiba_s06_unsol_event,
11329 .init_hook = alc262_toshiba_s06_init_hook,
11330 },
9f99a638
HM
11331 [ALC262_TOSHIBA_RX1] = {
11332 .mixers = { alc262_toshiba_rx1_mixer },
11333 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11334 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11335 .dac_nids = alc262_dac_nids,
11336 .hp_nid = 0x03,
11337 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11338 .channel_mode = alc262_modes,
11339 .input_mux = &alc262_capture_source,
11340 .unsol_event = alc262_hippo_unsol_event,
42171c17 11341 .init_hook = alc262_hippo_init_hook,
9f99a638 11342 },
ba340e82
TV
11343 [ALC262_TYAN] = {
11344 .mixers = { alc262_tyan_mixer },
11345 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11346 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11347 .dac_nids = alc262_dac_nids,
11348 .hp_nid = 0x02,
11349 .dig_out_nid = ALC262_DIGOUT_NID,
11350 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11351 .channel_mode = alc262_modes,
11352 .input_mux = &alc262_capture_source,
a9fd4f3f
TI
11353 .unsol_event = alc_automute_amp_unsol_event,
11354 .init_hook = alc262_tyan_init_hook,
ba340e82 11355 },
df694daa
KY
11356};
11357
11358static int patch_alc262(struct hda_codec *codec)
11359{
11360 struct alc_spec *spec;
11361 int board_config;
11362 int err;
11363
dc041e0b 11364 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11365 if (spec == NULL)
11366 return -ENOMEM;
11367
11368 codec->spec = spec;
11369#if 0
f12ab1e0
TI
11370 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11371 * under-run
11372 */
df694daa
KY
11373 {
11374 int tmp;
11375 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11376 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11377 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11378 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11379 }
11380#endif
11381
2c3bf9ab
TI
11382 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11383
f5fcc13c
TI
11384 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11385 alc262_models,
11386 alc262_cfg_tbl);
cd7509a4 11387
f5fcc13c 11388 if (board_config < 0) {
6c627f39
TI
11389 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11390 "trying auto-probe from BIOS...\n", codec->chip_name);
df694daa
KY
11391 board_config = ALC262_AUTO;
11392 }
11393
11394 if (board_config == ALC262_AUTO) {
11395 /* automatic parse from the BIOS config */
11396 err = alc262_parse_auto_config(codec);
11397 if (err < 0) {
11398 alc_free(codec);
11399 return err;
f12ab1e0 11400 } else if (!err) {
9c7f852e
TI
11401 printk(KERN_INFO
11402 "hda_codec: Cannot set up configuration "
11403 "from BIOS. Using base mode...\n");
df694daa
KY
11404 board_config = ALC262_BASIC;
11405 }
11406 }
11407
07eba61d
TI
11408 if (!spec->no_analog) {
11409 err = snd_hda_attach_beep_device(codec, 0x1);
11410 if (err < 0) {
11411 alc_free(codec);
11412 return err;
11413 }
680cd536
KK
11414 }
11415
df694daa
KY
11416 if (board_config != ALC262_AUTO)
11417 setup_preset(spec, &alc262_presets[board_config]);
11418
df694daa
KY
11419 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11420 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 11421
df694daa
KY
11422 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11423 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11424
61b9b9b1 11425 spec->capture_style = CAPT_MIX;
f12ab1e0 11426 if (!spec->adc_nids && spec->input_mux) {
df694daa 11427 /* check whether NID 0x07 is valid */
4a471b7d
TI
11428 unsigned int wcap = get_wcaps(codec, 0x07);
11429
f12ab1e0
TI
11430 /* get type */
11431 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
11432 if (wcap != AC_WID_AUD_IN) {
11433 spec->adc_nids = alc262_adc_nids_alt;
11434 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 11435 spec->capsrc_nids = alc262_capsrc_nids_alt;
df694daa
KY
11436 } else {
11437 spec->adc_nids = alc262_adc_nids;
11438 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 11439 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
11440 }
11441 }
e64f14f4 11442 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 11443 set_capture_mixer(spec);
07eba61d
TI
11444 if (!spec->no_analog)
11445 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 11446
2134ea4f
TI
11447 spec->vmaster_nid = 0x0c;
11448
df694daa
KY
11449 codec->patch_ops = alc_patch_ops;
11450 if (board_config == ALC262_AUTO)
ae6b813a 11451 spec->init_hook = alc262_auto_init;
cb53c626
TI
11452#ifdef CONFIG_SND_HDA_POWER_SAVE
11453 if (!spec->loopback.amplist)
11454 spec->loopback.amplist = alc262_loopbacks;
11455#endif
daead538 11456 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 11457
df694daa
KY
11458 return 0;
11459}
11460
a361d84b
KY
11461/*
11462 * ALC268 channel source setting (2 channel)
11463 */
11464#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11465#define alc268_modes alc260_modes
ea1fb29a 11466
a361d84b
KY
11467static hda_nid_t alc268_dac_nids[2] = {
11468 /* front, hp */
11469 0x02, 0x03
11470};
11471
11472static hda_nid_t alc268_adc_nids[2] = {
11473 /* ADC0-1 */
11474 0x08, 0x07
11475};
11476
11477static hda_nid_t alc268_adc_nids_alt[1] = {
11478 /* ADC0 */
11479 0x08
11480};
11481
e1406348
TI
11482static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11483
a361d84b
KY
11484static struct snd_kcontrol_new alc268_base_mixer[] = {
11485 /* output mixer control */
11486 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11487 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11488 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11489 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
11490 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11491 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11492 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
11493 { }
11494};
11495
42171c17
TI
11496static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11497 /* output mixer control */
11498 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11499 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11500 ALC262_HIPPO_MASTER_SWITCH,
11501 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11502 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11503 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11504 { }
11505};
11506
aef9d318
TI
11507/* bind Beep switches of both NID 0x0f and 0x10 */
11508static struct hda_bind_ctls alc268_bind_beep_sw = {
11509 .ops = &snd_hda_bind_sw,
11510 .values = {
11511 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11512 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11513 0
11514 },
11515};
11516
11517static struct snd_kcontrol_new alc268_beep_mixer[] = {
11518 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11519 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11520 { }
11521};
11522
d1a991a6
KY
11523static struct hda_verb alc268_eapd_verbs[] = {
11524 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11525 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11526 { }
11527};
11528
d273809e 11529/* Toshiba specific */
d273809e
TI
11530static struct hda_verb alc268_toshiba_verbs[] = {
11531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11532 { } /* end */
11533};
11534
8ef355da
KY
11535static struct hda_input_mux alc268_acer_lc_capture_source = {
11536 .num_items = 2,
11537 .items = {
11538 { "i-Mic", 0x6 },
11539 { "E-Mic", 0x0 },
11540 },
11541};
11542
d273809e 11543/* Acer specific */
889c4395 11544/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
11545static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11546 .ops = &snd_hda_bind_vol,
11547 .values = {
11548 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11549 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11550 0
11551 },
11552};
11553
889c4395
TI
11554/* mute/unmute internal speaker according to the hp jack and mute state */
11555static void alc268_acer_automute(struct hda_codec *codec, int force)
11556{
11557 struct alc_spec *spec = codec->spec;
11558 unsigned int mute;
11559
11560 if (force || !spec->sense_updated) {
11561 unsigned int present;
11562 present = snd_hda_codec_read(codec, 0x14, 0,
11563 AC_VERB_GET_PIN_SENSE, 0);
11564 spec->jack_present = (present & 0x80000000) != 0;
11565 spec->sense_updated = 1;
11566 }
11567 if (spec->jack_present)
11568 mute = HDA_AMP_MUTE; /* mute internal speaker */
11569 else /* unmute internal speaker if necessary */
11570 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11571 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11572 HDA_AMP_MUTE, mute);
11573}
11574
11575
11576/* bind hp and internal speaker mute (with plug check) */
11577static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11578 struct snd_ctl_elem_value *ucontrol)
11579{
11580 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11581 long *valp = ucontrol->value.integer.value;
11582 int change;
11583
11584 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11585 HDA_AMP_MUTE,
11586 valp[0] ? 0 : HDA_AMP_MUTE);
11587 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11588 HDA_AMP_MUTE,
11589 valp[1] ? 0 : HDA_AMP_MUTE);
11590 if (change)
11591 alc268_acer_automute(codec, 0);
11592 return change;
11593}
d273809e 11594
8ef355da
KY
11595static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11596 /* output mixer control */
11597 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11598 {
11599 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11600 .name = "Master Playback Switch",
11601 .info = snd_hda_mixer_amp_switch_info,
11602 .get = snd_hda_mixer_amp_switch_get,
11603 .put = alc268_acer_master_sw_put,
11604 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11605 },
11606 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11607 { }
11608};
11609
d273809e
TI
11610static struct snd_kcontrol_new alc268_acer_mixer[] = {
11611 /* output mixer control */
11612 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11613 {
11614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11615 .name = "Master Playback Switch",
11616 .info = snd_hda_mixer_amp_switch_info,
11617 .get = snd_hda_mixer_amp_switch_get,
11618 .put = alc268_acer_master_sw_put,
11619 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11620 },
33bf17ab
TI
11621 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11622 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11623 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
11624 { }
11625};
11626
c238b4f4
TI
11627static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11628 /* output mixer control */
11629 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11630 {
11631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11632 .name = "Master Playback Switch",
11633 .info = snd_hda_mixer_amp_switch_info,
11634 .get = snd_hda_mixer_amp_switch_get,
11635 .put = alc268_acer_master_sw_put,
11636 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11637 },
11638 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11639 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11640 { }
11641};
11642
8ef355da
KY
11643static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11644 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11646 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11647 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11648 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11649 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11650 { }
11651};
11652
d273809e 11653static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
11654 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11655 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
11656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
11658 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
11660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11661 { }
11662};
11663
11664/* unsolicited event for HP jack sensing */
42171c17
TI
11665#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11666#define alc268_toshiba_init_hook alc262_hippo_init_hook
d273809e
TI
11667
11668static void alc268_acer_unsol_event(struct hda_codec *codec,
11669 unsigned int res)
11670{
889c4395 11671 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11672 return;
11673 alc268_acer_automute(codec, 1);
11674}
11675
889c4395
TI
11676static void alc268_acer_init_hook(struct hda_codec *codec)
11677{
11678 alc268_acer_automute(codec, 1);
11679}
11680
8ef355da
KY
11681/* toggle speaker-output according to the hp-jack state */
11682static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11683{
11684 unsigned int present;
11685 unsigned char bits;
11686
11687 present = snd_hda_codec_read(codec, 0x15, 0,
11688 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11689 bits = present ? AMP_IN_MUTE(0) : 0;
11690 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11691 AMP_IN_MUTE(0), bits);
11692 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11693 AMP_IN_MUTE(0), bits);
11694}
11695
11696
11697static void alc268_acer_mic_automute(struct hda_codec *codec)
11698{
11699 unsigned int present;
11700
11701 present = snd_hda_codec_read(codec, 0x18, 0,
11702 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11703 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11704 present ? 0x0 : 0x6);
11705}
11706
11707static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11708 unsigned int res)
11709{
11710 if ((res >> 26) == ALC880_HP_EVENT)
11711 alc268_aspire_one_speaker_automute(codec);
11712 if ((res >> 26) == ALC880_MIC_EVENT)
11713 alc268_acer_mic_automute(codec);
11714}
11715
11716static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11717{
11718 alc268_aspire_one_speaker_automute(codec);
11719 alc268_acer_mic_automute(codec);
11720}
11721
3866f0b0
TI
11722static struct snd_kcontrol_new alc268_dell_mixer[] = {
11723 /* output mixer control */
11724 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11725 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11726 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11728 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11729 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11730 { }
11731};
11732
11733static struct hda_verb alc268_dell_verbs[] = {
11734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11736 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11737 { }
11738};
11739
11740/* mute/unmute internal speaker according to the hp jack and mute state */
a9fd4f3f 11741static void alc268_dell_init_hook(struct hda_codec *codec)
3866f0b0 11742{
a9fd4f3f 11743 struct alc_spec *spec = codec->spec;
3866f0b0 11744
a9fd4f3f
TI
11745 spec->autocfg.hp_pins[0] = 0x15;
11746 spec->autocfg.speaker_pins[0] = 0x14;
11747 alc_automute_pin(codec);
3866f0b0
TI
11748}
11749
eb5a6621
HRK
11750static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11751 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11752 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11753 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11754 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11755 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11756 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11757 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11758 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11759 { }
11760};
11761
11762static struct hda_verb alc267_quanta_il1_verbs[] = {
11763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11764 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11765 { }
11766};
11767
eb5a6621
HRK
11768static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11769{
11770 unsigned int present;
11771
11772 present = snd_hda_codec_read(codec, 0x18, 0,
11773 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11774 snd_hda_codec_write(codec, 0x23, 0,
11775 AC_VERB_SET_CONNECT_SEL,
11776 present ? 0x00 : 0x01);
11777}
11778
a9fd4f3f 11779static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
eb5a6621 11780{
a9fd4f3f
TI
11781 struct alc_spec *spec = codec->spec;
11782
11783 spec->autocfg.hp_pins[0] = 0x15;
11784 spec->autocfg.speaker_pins[0] = 0x14;
11785 alc_automute_pin(codec);
eb5a6621
HRK
11786 alc267_quanta_il1_mic_automute(codec);
11787}
11788
11789static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11790 unsigned int res)
11791{
11792 switch (res >> 26) {
eb5a6621
HRK
11793 case ALC880_MIC_EVENT:
11794 alc267_quanta_il1_mic_automute(codec);
11795 break;
a9fd4f3f
TI
11796 default:
11797 alc_sku_unsol_event(codec, res);
11798 break;
eb5a6621
HRK
11799 }
11800}
11801
a361d84b
KY
11802/*
11803 * generic initialization of ADC, input mixers and output mixers
11804 */
11805static struct hda_verb alc268_base_init_verbs[] = {
11806 /* Unmute DAC0-1 and set vol = 0 */
11807 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 11808 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11809
11810 /*
11811 * Set up output mixers (0x0c - 0x0e)
11812 */
11813 /* set vol=0 to output mixers */
11814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11815 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11816
11817 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11818 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11819
11820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11821 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11822 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11823 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11824 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11825 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11826 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11827 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11828
11829 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11832 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11833 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
11834
11835 /* set PCBEEP vol = 0, mute connections */
11836 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11837 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11838 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 11839
a9b3aa8a 11840 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 11841
a9b3aa8a
JZ
11842 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11844 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11845 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11846
a361d84b
KY
11847 { }
11848};
11849
11850/*
11851 * generic initialization of ADC, input mixers and output mixers
11852 */
11853static struct hda_verb alc268_volume_init_verbs[] = {
11854 /* set output DAC */
4cfb91c6
TI
11855 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11856 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11857
11858 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11860 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11861 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11862 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11863
a361d84b 11864 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11865 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11866 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11867
11868 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11869 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11870
aef9d318
TI
11871 /* set PCBEEP vol = 0, mute connections */
11872 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11873 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11874 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11875
11876 { }
11877};
11878
a361d84b
KY
11879static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11880 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11881 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11882 {
11883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11884 /* The multiple "Capture Source" controls confuse alsamixer
11885 * So call somewhat different..
a361d84b
KY
11886 */
11887 /* .name = "Capture Source", */
11888 .name = "Input Source",
11889 .count = 1,
54cbc9ab
TI
11890 .info = alc_mux_enum_info,
11891 .get = alc_mux_enum_get,
11892 .put = alc_mux_enum_put,
a361d84b
KY
11893 },
11894 { } /* end */
11895};
11896
11897static struct snd_kcontrol_new alc268_capture_mixer[] = {
11898 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11899 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11900 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11901 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11902 {
11903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11904 /* The multiple "Capture Source" controls confuse alsamixer
11905 * So call somewhat different..
a361d84b
KY
11906 */
11907 /* .name = "Capture Source", */
11908 .name = "Input Source",
11909 .count = 2,
54cbc9ab
TI
11910 .info = alc_mux_enum_info,
11911 .get = alc_mux_enum_get,
11912 .put = alc_mux_enum_put,
a361d84b
KY
11913 },
11914 { } /* end */
11915};
11916
11917static struct hda_input_mux alc268_capture_source = {
11918 .num_items = 4,
11919 .items = {
11920 { "Mic", 0x0 },
11921 { "Front Mic", 0x1 },
11922 { "Line", 0x2 },
11923 { "CD", 0x3 },
11924 },
11925};
11926
0ccb541c 11927static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
11928 .num_items = 3,
11929 .items = {
11930 { "Mic", 0x0 },
11931 { "Internal Mic", 0x1 },
11932 { "Line", 0x2 },
11933 },
11934};
11935
11936static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
11937 .num_items = 3,
11938 .items = {
11939 { "Mic", 0x0 },
11940 { "Internal Mic", 0x6 },
11941 { "Line", 0x2 },
11942 },
11943};
11944
86c53bd2
JW
11945#ifdef CONFIG_SND_DEBUG
11946static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11947 /* Volume widgets */
11948 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11949 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11950 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11951 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11952 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11953 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11954 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11955 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11956 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11957 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11958 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11959 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11960 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11961 /* The below appears problematic on some hardwares */
11962 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11963 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11964 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11965 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11966 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11967
11968 /* Modes for retasking pin widgets */
11969 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11970 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11971 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11972 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11973
11974 /* Controls for GPIO pins, assuming they are configured as outputs */
11975 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11976 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11977 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11978 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11979
11980 /* Switches to allow the digital SPDIF output pin to be enabled.
11981 * The ALC268 does not have an SPDIF input.
11982 */
11983 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11984
11985 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11986 * this output to turn on an external amplifier.
11987 */
11988 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11989 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11990
11991 { } /* end */
11992};
11993#endif
11994
a361d84b
KY
11995/* create input playback/capture controls for the given pin */
11996static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11997 const char *ctlname, int idx)
11998{
11999 char name[32];
12000 int err;
12001
12002 sprintf(name, "%s Playback Volume", ctlname);
12003 if (nid == 0x14) {
12004 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12005 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
12006 HDA_OUTPUT));
12007 if (err < 0)
12008 return err;
12009 } else if (nid == 0x15) {
12010 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12011 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
12012 HDA_OUTPUT));
12013 if (err < 0)
12014 return err;
12015 } else
12016 return -1;
12017 sprintf(name, "%s Playback Switch", ctlname);
12018 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12019 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12020 if (err < 0)
12021 return err;
12022 return 0;
12023}
12024
12025/* add playback controls from the parsed DAC table */
12026static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12027 const struct auto_pin_cfg *cfg)
12028{
12029 hda_nid_t nid;
12030 int err;
12031
12032 spec->multiout.num_dacs = 2; /* only use one dac */
12033 spec->multiout.dac_nids = spec->private_dac_nids;
12034 spec->multiout.dac_nids[0] = 2;
12035 spec->multiout.dac_nids[1] = 3;
12036
12037 nid = cfg->line_out_pins[0];
12038 if (nid)
ea1fb29a 12039 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
12040
12041 nid = cfg->speaker_pins[0];
12042 if (nid == 0x1d) {
12043 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12044 "Speaker Playback Volume",
12045 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12046 if (err < 0)
12047 return err;
12048 }
12049 nid = cfg->hp_pins[0];
12050 if (nid)
12051 alc268_new_analog_output(spec, nid, "Headphone", 0);
12052
12053 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12054 if (nid == 0x16) {
12055 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12056 "Mono Playback Switch",
12057 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
12058 if (err < 0)
12059 return err;
12060 }
ea1fb29a 12061 return 0;
a361d84b
KY
12062}
12063
12064/* create playback/capture controls for input pins */
12065static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
12066 const struct auto_pin_cfg *cfg)
12067{
61b9b9b1 12068 struct hda_input_mux *imux = &spec->private_imux[0];
a361d84b
KY
12069 int i, idx1;
12070
12071 for (i = 0; i < AUTO_PIN_LAST; i++) {
12072 switch(cfg->input_pins[i]) {
12073 case 0x18:
12074 idx1 = 0; /* Mic 1 */
12075 break;
12076 case 0x19:
12077 idx1 = 1; /* Mic 2 */
12078 break;
12079 case 0x1a:
12080 idx1 = 2; /* Line In */
12081 break;
ea1fb29a 12082 case 0x1c:
a361d84b
KY
12083 idx1 = 3; /* CD */
12084 break;
7194cae6
TI
12085 case 0x12:
12086 case 0x13:
12087 idx1 = 6; /* digital mics */
12088 break;
a361d84b
KY
12089 default:
12090 continue;
12091 }
12092 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12093 imux->items[imux->num_items].index = idx1;
ea1fb29a 12094 imux->num_items++;
a361d84b
KY
12095 }
12096 return 0;
12097}
12098
12099static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12100{
12101 struct alc_spec *spec = codec->spec;
12102 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12103 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12104 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12105 unsigned int dac_vol1, dac_vol2;
12106
12107 if (speaker_nid) {
12108 snd_hda_codec_write(codec, speaker_nid, 0,
12109 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12110 snd_hda_codec_write(codec, 0x0f, 0,
12111 AC_VERB_SET_AMP_GAIN_MUTE,
12112 AMP_IN_UNMUTE(1));
12113 snd_hda_codec_write(codec, 0x10, 0,
12114 AC_VERB_SET_AMP_GAIN_MUTE,
12115 AMP_IN_UNMUTE(1));
12116 } else {
12117 snd_hda_codec_write(codec, 0x0f, 0,
12118 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12119 snd_hda_codec_write(codec, 0x10, 0,
12120 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12121 }
12122
12123 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 12124 if (line_nid == 0x14)
a361d84b
KY
12125 dac_vol2 = AMP_OUT_ZERO;
12126 else if (line_nid == 0x15)
12127 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 12128 if (hp_nid == 0x14)
a361d84b
KY
12129 dac_vol2 = AMP_OUT_ZERO;
12130 else if (hp_nid == 0x15)
12131 dac_vol1 = AMP_OUT_ZERO;
12132 if (line_nid != 0x16 || hp_nid != 0x16 ||
12133 spec->autocfg.line_out_pins[1] != 0x16 ||
12134 spec->autocfg.line_out_pins[2] != 0x16)
12135 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12136
12137 snd_hda_codec_write(codec, 0x02, 0,
12138 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12139 snd_hda_codec_write(codec, 0x03, 0,
12140 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12141}
12142
12143/* pcm configuration: identiacal with ALC880 */
12144#define alc268_pcm_analog_playback alc880_pcm_analog_playback
12145#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 12146#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
12147#define alc268_pcm_digital_playback alc880_pcm_digital_playback
12148
12149/*
12150 * BIOS auto configuration
12151 */
12152static int alc268_parse_auto_config(struct hda_codec *codec)
12153{
12154 struct alc_spec *spec = codec->spec;
12155 int err;
12156 static hda_nid_t alc268_ignore[] = { 0 };
12157
12158 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12159 alc268_ignore);
12160 if (err < 0)
12161 return err;
7e0e44d4
TI
12162 if (!spec->autocfg.line_outs) {
12163 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12164 spec->multiout.max_channels = 2;
12165 spec->no_analog = 1;
12166 goto dig_only;
12167 }
a361d84b 12168 return 0; /* can't find valid BIOS pin config */
7e0e44d4 12169 }
a361d84b
KY
12170 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12171 if (err < 0)
12172 return err;
12173 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
12174 if (err < 0)
12175 return err;
12176
12177 spec->multiout.max_channels = 2;
12178
7e0e44d4 12179 dig_only:
a361d84b 12180 /* digital only support output */
7e0e44d4 12181 if (spec->autocfg.dig_outs) {
a361d84b 12182 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
12183 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12184 }
603c4019 12185 if (spec->kctls.list)
d88897ea 12186 add_mixer(spec, spec->kctls.list);
a361d84b 12187
892981ff 12188 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 12189 add_mixer(spec, alc268_beep_mixer);
aef9d318 12190
d88897ea 12191 add_verb(spec, alc268_volume_init_verbs);
a361d84b 12192 spec->num_mux_defs = 1;
61b9b9b1 12193 spec->input_mux = &spec->private_imux[0];
a361d84b 12194
776e184e
TI
12195 err = alc_auto_add_mic_boost(codec);
12196 if (err < 0)
12197 return err;
12198
a361d84b
KY
12199 return 1;
12200}
12201
12202#define alc268_auto_init_multi_out alc882_auto_init_multi_out
12203#define alc268_auto_init_hp_out alc882_auto_init_hp_out
12204#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12205
12206/* init callback for auto-configuration model -- overriding the default init */
12207static void alc268_auto_init(struct hda_codec *codec)
12208{
f6c7e546 12209 struct alc_spec *spec = codec->spec;
a361d84b
KY
12210 alc268_auto_init_multi_out(codec);
12211 alc268_auto_init_hp_out(codec);
12212 alc268_auto_init_mono_speaker_out(codec);
12213 alc268_auto_init_analog_input(codec);
f6c7e546 12214 if (spec->unsol_event)
7fb0d78f 12215 alc_inithook(codec);
a361d84b
KY
12216}
12217
12218/*
12219 * configuration and preset
12220 */
12221static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 12222 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 12223 [ALC268_3ST] = "3stack",
983f8ae4 12224 [ALC268_TOSHIBA] = "toshiba",
d273809e 12225 [ALC268_ACER] = "acer",
c238b4f4 12226 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 12227 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 12228 [ALC268_DELL] = "dell",
f12462c5 12229 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
12230#ifdef CONFIG_SND_DEBUG
12231 [ALC268_TEST] = "test",
12232#endif
a361d84b
KY
12233 [ALC268_AUTO] = "auto",
12234};
12235
12236static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 12237 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 12238 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 12239 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 12240 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 12241 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
12242 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12243 ALC268_ACER_ASPIRE_ONE),
3866f0b0 12244 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
57d13927 12245 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
8871e5b9
TI
12246 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12247 ALC268_TOSHIBA),
a361d84b 12248 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9
TI
12249 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12250 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12251 ALC268_TOSHIBA),
378bd6a5 12252 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 12253 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 12254 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 12255 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
12256 {}
12257};
12258
12259static struct alc_config_preset alc268_presets[] = {
eb5a6621 12260 [ALC267_QUANTA_IL1] = {
22971e3a 12261 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
eb5a6621
HRK
12262 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12263 alc267_quanta_il1_verbs },
12264 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12265 .dac_nids = alc268_dac_nids,
12266 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12267 .adc_nids = alc268_adc_nids_alt,
12268 .hp_nid = 0x03,
12269 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12270 .channel_mode = alc268_modes,
12271 .input_mux = &alc268_capture_source,
12272 .unsol_event = alc267_quanta_il1_unsol_event,
a9fd4f3f 12273 .init_hook = alc267_quanta_il1_init_hook,
eb5a6621 12274 },
a361d84b 12275 [ALC268_3ST] = {
aef9d318
TI
12276 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12277 alc268_beep_mixer },
a361d84b
KY
12278 .init_verbs = { alc268_base_init_verbs },
12279 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12280 .dac_nids = alc268_dac_nids,
12281 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12282 .adc_nids = alc268_adc_nids_alt,
e1406348 12283 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
12284 .hp_nid = 0x03,
12285 .dig_out_nid = ALC268_DIGOUT_NID,
12286 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12287 .channel_mode = alc268_modes,
12288 .input_mux = &alc268_capture_source,
12289 },
d1a991a6 12290 [ALC268_TOSHIBA] = {
42171c17 12291 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 12292 alc268_beep_mixer },
d273809e
TI
12293 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12294 alc268_toshiba_verbs },
d1a991a6
KY
12295 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12296 .dac_nids = alc268_dac_nids,
12297 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12298 .adc_nids = alc268_adc_nids_alt,
e1406348 12299 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
12300 .hp_nid = 0x03,
12301 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12302 .channel_mode = alc268_modes,
12303 .input_mux = &alc268_capture_source,
d273809e 12304 .unsol_event = alc268_toshiba_unsol_event,
42171c17 12305 .init_hook = alc268_toshiba_init_hook,
d273809e
TI
12306 },
12307 [ALC268_ACER] = {
aef9d318
TI
12308 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12309 alc268_beep_mixer },
d273809e
TI
12310 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12311 alc268_acer_verbs },
12312 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12313 .dac_nids = alc268_dac_nids,
12314 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12315 .adc_nids = alc268_adc_nids_alt,
e1406348 12316 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
12317 .hp_nid = 0x02,
12318 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12319 .channel_mode = alc268_modes,
0ccb541c 12320 .input_mux = &alc268_acer_capture_source,
d273809e 12321 .unsol_event = alc268_acer_unsol_event,
889c4395 12322 .init_hook = alc268_acer_init_hook,
d1a991a6 12323 },
c238b4f4
TI
12324 [ALC268_ACER_DMIC] = {
12325 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12326 alc268_beep_mixer },
12327 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12328 alc268_acer_verbs },
12329 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12330 .dac_nids = alc268_dac_nids,
12331 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12332 .adc_nids = alc268_adc_nids_alt,
12333 .capsrc_nids = alc268_capsrc_nids,
12334 .hp_nid = 0x02,
12335 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12336 .channel_mode = alc268_modes,
12337 .input_mux = &alc268_acer_dmic_capture_source,
12338 .unsol_event = alc268_acer_unsol_event,
12339 .init_hook = alc268_acer_init_hook,
12340 },
8ef355da
KY
12341 [ALC268_ACER_ASPIRE_ONE] = {
12342 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a
TI
12343 alc268_beep_mixer,
12344 alc268_capture_alt_mixer },
8ef355da
KY
12345 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12346 alc268_acer_aspire_one_verbs },
12347 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12348 .dac_nids = alc268_dac_nids,
12349 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12350 .adc_nids = alc268_adc_nids_alt,
12351 .capsrc_nids = alc268_capsrc_nids,
12352 .hp_nid = 0x03,
12353 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12354 .channel_mode = alc268_modes,
12355 .input_mux = &alc268_acer_lc_capture_source,
12356 .unsol_event = alc268_acer_lc_unsol_event,
12357 .init_hook = alc268_acer_lc_init_hook,
12358 },
3866f0b0 12359 [ALC268_DELL] = {
aef9d318 12360 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
12361 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12362 alc268_dell_verbs },
12363 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12364 .dac_nids = alc268_dac_nids,
12365 .hp_nid = 0x02,
12366 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12367 .channel_mode = alc268_modes,
a9fd4f3f 12368 .unsol_event = alc_sku_unsol_event,
3866f0b0
TI
12369 .init_hook = alc268_dell_init_hook,
12370 .input_mux = &alc268_capture_source,
12371 },
f12462c5 12372 [ALC268_ZEPTO] = {
aef9d318
TI
12373 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12374 alc268_beep_mixer },
f12462c5
MT
12375 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12376 alc268_toshiba_verbs },
12377 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12378 .dac_nids = alc268_dac_nids,
12379 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12380 .adc_nids = alc268_adc_nids_alt,
e1406348 12381 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
12382 .hp_nid = 0x03,
12383 .dig_out_nid = ALC268_DIGOUT_NID,
12384 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12385 .channel_mode = alc268_modes,
12386 .input_mux = &alc268_capture_source,
12387 .unsol_event = alc268_toshiba_unsol_event,
42171c17 12388 .init_hook = alc268_toshiba_init_hook
f12462c5 12389 },
86c53bd2
JW
12390#ifdef CONFIG_SND_DEBUG
12391 [ALC268_TEST] = {
12392 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12393 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12394 alc268_volume_init_verbs },
12395 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12396 .dac_nids = alc268_dac_nids,
12397 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12398 .adc_nids = alc268_adc_nids_alt,
e1406348 12399 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
12400 .hp_nid = 0x03,
12401 .dig_out_nid = ALC268_DIGOUT_NID,
12402 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12403 .channel_mode = alc268_modes,
12404 .input_mux = &alc268_capture_source,
12405 },
12406#endif
a361d84b
KY
12407};
12408
12409static int patch_alc268(struct hda_codec *codec)
12410{
12411 struct alc_spec *spec;
12412 int board_config;
22971e3a 12413 int i, has_beep, err;
a361d84b
KY
12414
12415 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12416 if (spec == NULL)
12417 return -ENOMEM;
12418
12419 codec->spec = spec;
12420
12421 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12422 alc268_models,
12423 alc268_cfg_tbl);
12424
12425 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
6c627f39
TI
12426 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12427 "trying auto-probe from BIOS...\n", codec->chip_name);
a361d84b
KY
12428 board_config = ALC268_AUTO;
12429 }
12430
12431 if (board_config == ALC268_AUTO) {
12432 /* automatic parse from the BIOS config */
12433 err = alc268_parse_auto_config(codec);
12434 if (err < 0) {
12435 alc_free(codec);
12436 return err;
12437 } else if (!err) {
12438 printk(KERN_INFO
12439 "hda_codec: Cannot set up configuration "
12440 "from BIOS. Using base mode...\n");
12441 board_config = ALC268_3ST;
12442 }
12443 }
12444
12445 if (board_config != ALC268_AUTO)
12446 setup_preset(spec, &alc268_presets[board_config]);
12447
a361d84b
KY
12448 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12449 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 12450 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 12451
a361d84b
KY
12452 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12453
22971e3a
TI
12454 has_beep = 0;
12455 for (i = 0; i < spec->num_mixers; i++) {
12456 if (spec->mixers[i] == alc268_beep_mixer) {
12457 has_beep = 1;
12458 break;
12459 }
12460 }
12461
12462 if (has_beep) {
12463 err = snd_hda_attach_beep_device(codec, 0x1);
12464 if (err < 0) {
12465 alc_free(codec);
12466 return err;
12467 }
12468 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12469 /* override the amp caps for beep generator */
12470 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
12471 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12472 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12473 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12474 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 12475 }
aef9d318 12476
7e0e44d4 12477 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
12478 /* check whether NID 0x07 is valid */
12479 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 12480 int i;
3866f0b0
TI
12481
12482 /* get type */
12483 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 12484 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
12485 spec->adc_nids = alc268_adc_nids_alt;
12486 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
d88897ea 12487 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
12488 } else {
12489 spec->adc_nids = alc268_adc_nids;
12490 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 12491 add_mixer(spec, alc268_capture_mixer);
a361d84b 12492 }
e1406348 12493 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
12494 /* set default input source */
12495 for (i = 0; i < spec->num_adc_nids; i++)
12496 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12497 0, AC_VERB_SET_CONNECT_SEL,
12498 spec->input_mux->items[0].index);
a361d84b 12499 }
2134ea4f
TI
12500
12501 spec->vmaster_nid = 0x02;
12502
a361d84b
KY
12503 codec->patch_ops = alc_patch_ops;
12504 if (board_config == ALC268_AUTO)
12505 spec->init_hook = alc268_auto_init;
ea1fb29a 12506
daead538
TI
12507 codec->proc_widget_hook = print_realtek_coef;
12508
a361d84b
KY
12509 return 0;
12510}
12511
f6a92248
KY
12512/*
12513 * ALC269 channel source setting (2 channel)
12514 */
12515#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12516
12517#define alc269_dac_nids alc260_dac_nids
12518
12519static hda_nid_t alc269_adc_nids[1] = {
12520 /* ADC1 */
f53281e6
KY
12521 0x08,
12522};
12523
e01bf509
TI
12524static hda_nid_t alc269_capsrc_nids[1] = {
12525 0x23,
12526};
12527
12528/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12529 * not a mux!
12530 */
12531
f53281e6
KY
12532static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12533 .num_items = 2,
12534 .items = {
12535 { "i-Mic", 0x5 },
12536 { "e-Mic", 0x0 },
12537 },
12538};
12539
12540static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12541 .num_items = 2,
12542 .items = {
12543 { "i-Mic", 0x1 },
12544 { "e-Mic", 0x0 },
12545 },
f6a92248
KY
12546};
12547
12548#define alc269_modes alc260_modes
12549#define alc269_capture_source alc880_lg_lw_capture_source
12550
12551static struct snd_kcontrol_new alc269_base_mixer[] = {
12552 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12553 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12554 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12555 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12558 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12559 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12561 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12563 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12564 { } /* end */
12565};
12566
60db6b53
KY
12567static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12568 /* output mixer control */
12569 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12570 {
12571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12572 .name = "Master Playback Switch",
12573 .info = snd_hda_mixer_amp_switch_info,
12574 .get = snd_hda_mixer_amp_switch_get,
12575 .put = alc268_acer_master_sw_put,
12576 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12577 },
12578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12580 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12581 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12582 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12583 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
12584 { }
12585};
12586
64154835
TV
12587static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12588 /* output mixer control */
12589 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12590 {
12591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12592 .name = "Master Playback Switch",
12593 .info = snd_hda_mixer_amp_switch_info,
12594 .get = snd_hda_mixer_amp_switch_get,
12595 .put = alc268_acer_master_sw_put,
12596 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12597 },
12598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12600 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12601 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12602 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12603 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12604 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12605 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12606 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
12607 { }
12608};
12609
f53281e6
KY
12610/* bind volumes of both NID 0x0c and 0x0d */
12611static struct hda_bind_ctls alc269_epc_bind_vol = {
12612 .ops = &snd_hda_bind_vol,
12613 .values = {
12614 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12615 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12616 0
12617 },
12618};
12619
12620static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12621 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12622 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12623 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12624 { } /* end */
12625};
12626
f53281e6
KY
12627/* capture mixer elements */
12628static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12629 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12630 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
12631 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12632 { } /* end */
12633};
12634
12635/* FSC amilo */
12636static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12637 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12639 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
f53281e6
KY
12640 { } /* end */
12641};
12642
60db6b53
KY
12643static struct hda_verb alc269_quanta_fl1_verbs[] = {
12644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12645 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12647 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12648 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12649 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12650 { }
12651};
f6a92248 12652
64154835
TV
12653static struct hda_verb alc269_lifebook_verbs[] = {
12654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12655 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12656 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12658 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12660 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12661 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12662 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12663 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12664 { }
12665};
12666
60db6b53
KY
12667/* toggle speaker-output according to the hp-jack state */
12668static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12669{
12670 unsigned int present;
12671 unsigned char bits;
f6a92248 12672
60db6b53
KY
12673 present = snd_hda_codec_read(codec, 0x15, 0,
12674 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12675 bits = present ? AMP_IN_MUTE(0) : 0;
12676 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12677 AMP_IN_MUTE(0), bits);
12678 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12679 AMP_IN_MUTE(0), bits);
f6a92248 12680
60db6b53
KY
12681 snd_hda_codec_write(codec, 0x20, 0,
12682 AC_VERB_SET_COEF_INDEX, 0x0c);
12683 snd_hda_codec_write(codec, 0x20, 0,
12684 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 12685
60db6b53
KY
12686 snd_hda_codec_write(codec, 0x20, 0,
12687 AC_VERB_SET_COEF_INDEX, 0x0c);
12688 snd_hda_codec_write(codec, 0x20, 0,
12689 AC_VERB_SET_PROC_COEF, 0x480);
12690}
f6a92248 12691
64154835
TV
12692/* toggle speaker-output according to the hp-jacks state */
12693static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12694{
12695 unsigned int present;
12696 unsigned char bits;
12697
12698 /* Check laptop headphone socket */
12699 present = snd_hda_codec_read(codec, 0x15, 0,
12700 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12701
12702 /* Check port replicator headphone socket */
12703 present |= snd_hda_codec_read(codec, 0x1a, 0,
12704 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12705
12706 bits = present ? AMP_IN_MUTE(0) : 0;
12707 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12708 AMP_IN_MUTE(0), bits);
12709 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12710 AMP_IN_MUTE(0), bits);
12711
12712 snd_hda_codec_write(codec, 0x20, 0,
12713 AC_VERB_SET_COEF_INDEX, 0x0c);
12714 snd_hda_codec_write(codec, 0x20, 0,
12715 AC_VERB_SET_PROC_COEF, 0x680);
12716
12717 snd_hda_codec_write(codec, 0x20, 0,
12718 AC_VERB_SET_COEF_INDEX, 0x0c);
12719 snd_hda_codec_write(codec, 0x20, 0,
12720 AC_VERB_SET_PROC_COEF, 0x480);
12721}
12722
60db6b53
KY
12723static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12724{
12725 unsigned int present;
f6a92248 12726
60db6b53
KY
12727 present = snd_hda_codec_read(codec, 0x18, 0,
12728 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12729 snd_hda_codec_write(codec, 0x23, 0,
12730 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12731}
f6a92248 12732
64154835
TV
12733static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12734{
12735 unsigned int present_laptop;
12736 unsigned int present_dock;
12737
12738 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12739 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12740
12741 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12742 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12743
12744 /* Laptop mic port overrides dock mic port, design decision */
12745 if (present_dock)
12746 snd_hda_codec_write(codec, 0x23, 0,
12747 AC_VERB_SET_CONNECT_SEL, 0x3);
12748 if (present_laptop)
12749 snd_hda_codec_write(codec, 0x23, 0,
12750 AC_VERB_SET_CONNECT_SEL, 0x0);
12751 if (!present_dock && !present_laptop)
12752 snd_hda_codec_write(codec, 0x23, 0,
12753 AC_VERB_SET_CONNECT_SEL, 0x1);
12754}
12755
60db6b53
KY
12756static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12757 unsigned int res)
12758{
12759 if ((res >> 26) == ALC880_HP_EVENT)
12760 alc269_quanta_fl1_speaker_automute(codec);
12761 if ((res >> 26) == ALC880_MIC_EVENT)
12762 alc269_quanta_fl1_mic_automute(codec);
12763}
f6a92248 12764
64154835
TV
12765static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12766 unsigned int res)
12767{
12768 if ((res >> 26) == ALC880_HP_EVENT)
12769 alc269_lifebook_speaker_automute(codec);
12770 if ((res >> 26) == ALC880_MIC_EVENT)
12771 alc269_lifebook_mic_autoswitch(codec);
12772}
12773
60db6b53
KY
12774static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12775{
12776 alc269_quanta_fl1_speaker_automute(codec);
12777 alc269_quanta_fl1_mic_automute(codec);
12778}
f6a92248 12779
64154835
TV
12780static void alc269_lifebook_init_hook(struct hda_codec *codec)
12781{
12782 alc269_lifebook_speaker_automute(codec);
12783 alc269_lifebook_mic_autoswitch(codec);
12784}
12785
f53281e6
KY
12786static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12787 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12788 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12789 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12791 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12792 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12793 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12794 {}
12795};
12796
12797static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12799 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12800 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12801 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12802 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12803 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12804 {}
12805};
12806
12807/* toggle speaker-output according to the hp-jack state */
12808static void alc269_speaker_automute(struct hda_codec *codec)
12809{
12810 unsigned int present;
60db6b53 12811 unsigned char bits;
f53281e6
KY
12812
12813 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 12814 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
12815 bits = present ? AMP_IN_MUTE(0) : 0;
12816 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 12817 AMP_IN_MUTE(0), bits);
f53281e6 12818 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 12819 AMP_IN_MUTE(0), bits);
f53281e6
KY
12820}
12821
12822static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12823{
12824 unsigned int present;
12825
60db6b53
KY
12826 present = snd_hda_codec_read(codec, 0x18, 0,
12827 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12828 snd_hda_codec_write(codec, 0x23, 0,
12829 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
12830}
12831
12832static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12833{
12834 unsigned int present;
12835
60db6b53
KY
12836 present = snd_hda_codec_read(codec, 0x18, 0,
12837 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 12838 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12839 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 12840 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12841 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
12842}
12843
12844/* unsolicited event for HP jack sensing */
12845static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 12846 unsigned int res)
f53281e6
KY
12847{
12848 if ((res >> 26) == ALC880_HP_EVENT)
12849 alc269_speaker_automute(codec);
12850
12851 if ((res >> 26) == ALC880_MIC_EVENT)
12852 alc269_eeepc_dmic_automute(codec);
12853}
12854
12855static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12856{
12857 alc269_speaker_automute(codec);
12858 alc269_eeepc_dmic_automute(codec);
12859}
12860
12861/* unsolicited event for HP jack sensing */
12862static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 12863 unsigned int res)
f53281e6
KY
12864{
12865 if ((res >> 26) == ALC880_HP_EVENT)
12866 alc269_speaker_automute(codec);
12867
12868 if ((res >> 26) == ALC880_MIC_EVENT)
12869 alc269_eeepc_amic_automute(codec);
12870}
12871
12872static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12873{
12874 alc269_speaker_automute(codec);
12875 alc269_eeepc_amic_automute(codec);
12876}
12877
60db6b53
KY
12878/*
12879 * generic initialization of ADC, input mixers and output mixers
12880 */
12881static struct hda_verb alc269_init_verbs[] = {
12882 /*
12883 * Unmute ADC0 and set the default input to mic-in
12884 */
12885 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12886
12887 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12888 * analog-loopback mixer widget
12889 * Note: PASD motherboards uses the Line In 2 as the input for
12890 * front panel mic (mic 2)
12891 */
12892 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12897 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12898
12899 /*
12900 * Set up output mixers (0x0c - 0x0e)
12901 */
12902 /* set vol=0 to output mixers */
12903 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12904 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12905
12906 /* set up input amps for analog loopback */
12907 /* Amp Indices: DAC = 0, mixer = 1 */
12908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12913 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12914
12915 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12916 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12917 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12918 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12919 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12920 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12921 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12922
12923 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12925 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12926 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12927 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12928 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12929 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12930
12931 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12933
12934 /* FIXME: use matrix-type input source selection */
12935 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12936 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12937 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12938 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12940 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12941
12942 /* set EAPD */
12943 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12944 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12945 { }
12946};
12947
f6a92248
KY
12948/* add playback controls from the parsed DAC table */
12949static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12950 const struct auto_pin_cfg *cfg)
12951{
12952 hda_nid_t nid;
12953 int err;
12954
12955 spec->multiout.num_dacs = 1; /* only use one dac */
12956 spec->multiout.dac_nids = spec->private_dac_nids;
12957 spec->multiout.dac_nids[0] = 2;
12958
12959 nid = cfg->line_out_pins[0];
12960 if (nid) {
12961 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12962 "Front Playback Volume",
12963 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12964 if (err < 0)
12965 return err;
12966 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12967 "Front Playback Switch",
12968 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12969 if (err < 0)
12970 return err;
12971 }
12972
12973 nid = cfg->speaker_pins[0];
12974 if (nid) {
12975 if (!cfg->line_out_pins[0]) {
12976 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12977 "Speaker Playback Volume",
12978 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12979 HDA_OUTPUT));
12980 if (err < 0)
12981 return err;
12982 }
12983 if (nid == 0x16) {
12984 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12985 "Speaker Playback Switch",
12986 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12987 HDA_OUTPUT));
12988 if (err < 0)
12989 return err;
12990 } else {
12991 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12992 "Speaker Playback Switch",
12993 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12994 HDA_OUTPUT));
12995 if (err < 0)
12996 return err;
12997 }
12998 }
12999 nid = cfg->hp_pins[0];
13000 if (nid) {
13001 /* spec->multiout.hp_nid = 2; */
13002 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
13003 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13004 "Headphone Playback Volume",
13005 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
13006 HDA_OUTPUT));
13007 if (err < 0)
13008 return err;
13009 }
13010 if (nid == 0x16) {
13011 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13012 "Headphone Playback Switch",
13013 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13014 HDA_OUTPUT));
13015 if (err < 0)
13016 return err;
13017 } else {
13018 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13019 "Headphone Playback Switch",
13020 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13021 HDA_OUTPUT));
13022 if (err < 0)
13023 return err;
13024 }
13025 }
13026 return 0;
13027}
13028
ee956e09
TI
13029static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
13030 const struct auto_pin_cfg *cfg)
13031{
13032 int err;
13033
13034 err = alc880_auto_create_analog_input_ctls(spec, cfg);
13035 if (err < 0)
13036 return err;
13037 /* digital-mic input pin is excluded in alc880_auto_create..()
13038 * because it's under 0x18
13039 */
13040 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
13041 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
61b9b9b1 13042 struct hda_input_mux *imux = &spec->private_imux[0];
ee956e09
TI
13043 imux->items[imux->num_items].label = "Int Mic";
13044 imux->items[imux->num_items].index = 0x05;
13045 imux->num_items++;
13046 }
13047 return 0;
13048}
f6a92248
KY
13049
13050#ifdef CONFIG_SND_HDA_POWER_SAVE
13051#define alc269_loopbacks alc880_loopbacks
13052#endif
13053
13054/* pcm configuration: identiacal with ALC880 */
13055#define alc269_pcm_analog_playback alc880_pcm_analog_playback
13056#define alc269_pcm_analog_capture alc880_pcm_analog_capture
13057#define alc269_pcm_digital_playback alc880_pcm_digital_playback
13058#define alc269_pcm_digital_capture alc880_pcm_digital_capture
13059
f03d3115
TI
13060static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13061 .substreams = 1,
13062 .channels_min = 2,
13063 .channels_max = 8,
13064 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13065 /* NID is set in alc_build_pcms */
13066 .ops = {
13067 .open = alc880_playback_pcm_open,
13068 .prepare = alc880_playback_pcm_prepare,
13069 .cleanup = alc880_playback_pcm_cleanup
13070 },
13071};
13072
13073static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13074 .substreams = 1,
13075 .channels_min = 2,
13076 .channels_max = 2,
13077 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13078 /* NID is set in alc_build_pcms */
13079};
13080
f6a92248
KY
13081/*
13082 * BIOS auto configuration
13083 */
13084static int alc269_parse_auto_config(struct hda_codec *codec)
13085{
13086 struct alc_spec *spec = codec->spec;
cfb9fb55 13087 int err;
f6a92248
KY
13088 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13089
13090 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13091 alc269_ignore);
13092 if (err < 0)
13093 return err;
13094
13095 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13096 if (err < 0)
13097 return err;
13098 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
13099 if (err < 0)
13100 return err;
13101
13102 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13103
0852d7a6 13104 if (spec->autocfg.dig_outs)
f6a92248
KY
13105 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13106
603c4019 13107 if (spec->kctls.list)
d88897ea 13108 add_mixer(spec, spec->kctls.list);
f6a92248 13109
d88897ea 13110 add_verb(spec, alc269_init_verbs);
f6a92248 13111 spec->num_mux_defs = 1;
61b9b9b1 13112 spec->input_mux = &spec->private_imux[0];
e01bf509
TI
13113 /* set default input source */
13114 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13115 0, AC_VERB_SET_CONNECT_SEL,
13116 spec->input_mux->items[0].index);
f6a92248
KY
13117
13118 err = alc_auto_add_mic_boost(codec);
13119 if (err < 0)
13120 return err;
13121
7e0e44d4 13122 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 13123 set_capture_mixer(spec);
f53281e6 13124
f6a92248
KY
13125 return 1;
13126}
13127
13128#define alc269_auto_init_multi_out alc882_auto_init_multi_out
13129#define alc269_auto_init_hp_out alc882_auto_init_hp_out
13130#define alc269_auto_init_analog_input alc882_auto_init_analog_input
13131
13132
13133/* init callback for auto-configuration model -- overriding the default init */
13134static void alc269_auto_init(struct hda_codec *codec)
13135{
f6c7e546 13136 struct alc_spec *spec = codec->spec;
f6a92248
KY
13137 alc269_auto_init_multi_out(codec);
13138 alc269_auto_init_hp_out(codec);
13139 alc269_auto_init_analog_input(codec);
f6c7e546 13140 if (spec->unsol_event)
7fb0d78f 13141 alc_inithook(codec);
f6a92248
KY
13142}
13143
13144/*
13145 * configuration and preset
13146 */
13147static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 13148 [ALC269_BASIC] = "basic",
2922c9af
TI
13149 [ALC269_QUANTA_FL1] = "quanta",
13150 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
26f5df26 13151 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
64154835
TV
13152 [ALC269_FUJITSU] = "fujitsu",
13153 [ALC269_LIFEBOOK] = "lifebook"
f6a92248
KY
13154};
13155
13156static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 13157 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
13158 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13159 ALC269_ASUS_EEEPC_P703),
622e84cd
KY
13160 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13161 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13162 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13163 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13164 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13165 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
f53281e6
KY
13166 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13167 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
13168 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13169 ALC269_ASUS_EEEPC_P901),
622e84cd 13170 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
26f5df26 13171 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
64154835 13172 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
f6a92248
KY
13173 {}
13174};
13175
13176static struct alc_config_preset alc269_presets[] = {
13177 [ALC269_BASIC] = {
f9e336f6 13178 .mixers = { alc269_base_mixer },
f6a92248
KY
13179 .init_verbs = { alc269_init_verbs },
13180 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13181 .dac_nids = alc269_dac_nids,
13182 .hp_nid = 0x03,
13183 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13184 .channel_mode = alc269_modes,
13185 .input_mux = &alc269_capture_source,
13186 },
60db6b53
KY
13187 [ALC269_QUANTA_FL1] = {
13188 .mixers = { alc269_quanta_fl1_mixer },
13189 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13190 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13191 .dac_nids = alc269_dac_nids,
13192 .hp_nid = 0x03,
13193 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13194 .channel_mode = alc269_modes,
13195 .input_mux = &alc269_capture_source,
13196 .unsol_event = alc269_quanta_fl1_unsol_event,
13197 .init_hook = alc269_quanta_fl1_init_hook,
13198 },
f53281e6 13199 [ALC269_ASUS_EEEPC_P703] = {
f9e336f6
TI
13200 .mixers = { alc269_eeepc_mixer },
13201 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13202 .init_verbs = { alc269_init_verbs,
13203 alc269_eeepc_amic_init_verbs },
13204 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13205 .dac_nids = alc269_dac_nids,
13206 .hp_nid = 0x03,
13207 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13208 .channel_mode = alc269_modes,
13209 .input_mux = &alc269_eeepc_amic_capture_source,
13210 .unsol_event = alc269_eeepc_amic_unsol_event,
13211 .init_hook = alc269_eeepc_amic_inithook,
13212 },
13213 [ALC269_ASUS_EEEPC_P901] = {
f9e336f6
TI
13214 .mixers = { alc269_eeepc_mixer },
13215 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13216 .init_verbs = { alc269_init_verbs,
13217 alc269_eeepc_dmic_init_verbs },
13218 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13219 .dac_nids = alc269_dac_nids,
13220 .hp_nid = 0x03,
13221 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13222 .channel_mode = alc269_modes,
13223 .input_mux = &alc269_eeepc_dmic_capture_source,
13224 .unsol_event = alc269_eeepc_dmic_unsol_event,
13225 .init_hook = alc269_eeepc_dmic_inithook,
13226 },
26f5df26 13227 [ALC269_FUJITSU] = {
45bdd1c1 13228 .mixers = { alc269_fujitsu_mixer },
26f5df26
TI
13229 .cap_mixer = alc269_epc_capture_mixer,
13230 .init_verbs = { alc269_init_verbs,
13231 alc269_eeepc_dmic_init_verbs },
13232 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13233 .dac_nids = alc269_dac_nids,
13234 .hp_nid = 0x03,
13235 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13236 .channel_mode = alc269_modes,
13237 .input_mux = &alc269_eeepc_dmic_capture_source,
13238 .unsol_event = alc269_eeepc_dmic_unsol_event,
13239 .init_hook = alc269_eeepc_dmic_inithook,
13240 },
64154835
TV
13241 [ALC269_LIFEBOOK] = {
13242 .mixers = { alc269_lifebook_mixer },
13243 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13244 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13245 .dac_nids = alc269_dac_nids,
13246 .hp_nid = 0x03,
13247 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13248 .channel_mode = alc269_modes,
13249 .input_mux = &alc269_capture_source,
13250 .unsol_event = alc269_lifebook_unsol_event,
13251 .init_hook = alc269_lifebook_init_hook,
13252 },
f6a92248
KY
13253};
13254
13255static int patch_alc269(struct hda_codec *codec)
13256{
13257 struct alc_spec *spec;
13258 int board_config;
13259 int err;
13260
13261 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13262 if (spec == NULL)
13263 return -ENOMEM;
13264
13265 codec->spec = spec;
13266
2c3bf9ab
TI
13267 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13268
f6a92248
KY
13269 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13270 alc269_models,
13271 alc269_cfg_tbl);
13272
13273 if (board_config < 0) {
6c627f39
TI
13274 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13275 "trying auto-probe from BIOS...\n", codec->chip_name);
f6a92248
KY
13276 board_config = ALC269_AUTO;
13277 }
13278
13279 if (board_config == ALC269_AUTO) {
13280 /* automatic parse from the BIOS config */
13281 err = alc269_parse_auto_config(codec);
13282 if (err < 0) {
13283 alc_free(codec);
13284 return err;
13285 } else if (!err) {
13286 printk(KERN_INFO
13287 "hda_codec: Cannot set up configuration "
13288 "from BIOS. Using base mode...\n");
13289 board_config = ALC269_BASIC;
13290 }
13291 }
13292
680cd536
KK
13293 err = snd_hda_attach_beep_device(codec, 0x1);
13294 if (err < 0) {
13295 alc_free(codec);
13296 return err;
13297 }
13298
f6a92248
KY
13299 if (board_config != ALC269_AUTO)
13300 setup_preset(spec, &alc269_presets[board_config]);
13301
f03d3115
TI
13302 if (codec->subsystem_id == 0x17aa3bf8) {
13303 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13304 * fix the sample rate of analog I/O to 44.1kHz
13305 */
13306 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13307 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13308 } else {
13309 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13310 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13311 }
f6a92248
KY
13312 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13313 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13314
13315 spec->adc_nids = alc269_adc_nids;
13316 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 13317 spec->capsrc_nids = alc269_capsrc_nids;
f9e336f6
TI
13318 if (!spec->cap_mixer)
13319 set_capture_mixer(spec);
45bdd1c1 13320 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248
KY
13321
13322 codec->patch_ops = alc_patch_ops;
13323 if (board_config == ALC269_AUTO)
13324 spec->init_hook = alc269_auto_init;
13325#ifdef CONFIG_SND_HDA_POWER_SAVE
13326 if (!spec->loopback.amplist)
13327 spec->loopback.amplist = alc269_loopbacks;
13328#endif
daead538 13329 codec->proc_widget_hook = print_realtek_coef;
f6a92248
KY
13330
13331 return 0;
13332}
13333
df694daa
KY
13334/*
13335 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13336 */
13337
13338/*
13339 * set the path ways for 2 channel output
13340 * need to set the codec line out and mic 1 pin widgets to inputs
13341 */
13342static struct hda_verb alc861_threestack_ch2_init[] = {
13343 /* set pin widget 1Ah (line in) for input */
13344 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13345 /* set pin widget 18h (mic1/2) for input, for mic also enable
13346 * the vref
13347 */
df694daa
KY
13348 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13349
9c7f852e
TI
13350 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13351#if 0
13352 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13353 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13354#endif
df694daa
KY
13355 { } /* end */
13356};
13357/*
13358 * 6ch mode
13359 * need to set the codec line out and mic 1 pin widgets to outputs
13360 */
13361static struct hda_verb alc861_threestack_ch6_init[] = {
13362 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13363 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13364 /* set pin widget 18h (mic1) for output (CLFE)*/
13365 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13366
13367 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 13368 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 13369
9c7f852e
TI
13370 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13371#if 0
13372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13373 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13374#endif
df694daa
KY
13375 { } /* end */
13376};
13377
13378static struct hda_channel_mode alc861_threestack_modes[2] = {
13379 { 2, alc861_threestack_ch2_init },
13380 { 6, alc861_threestack_ch6_init },
13381};
22309c3e
TI
13382/* Set mic1 as input and unmute the mixer */
13383static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13384 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13385 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13386 { } /* end */
13387};
13388/* Set mic1 as output and mute mixer */
13389static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13390 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13391 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13392 { } /* end */
13393};
13394
13395static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13396 { 2, alc861_uniwill_m31_ch2_init },
13397 { 4, alc861_uniwill_m31_ch4_init },
13398};
df694daa 13399
7cdbff94
MD
13400/* Set mic1 and line-in as input and unmute the mixer */
13401static struct hda_verb alc861_asus_ch2_init[] = {
13402 /* set pin widget 1Ah (line in) for input */
13403 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13404 /* set pin widget 18h (mic1/2) for input, for mic also enable
13405 * the vref
13406 */
7cdbff94
MD
13407 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13408
13409 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13410#if 0
13411 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13412 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13413#endif
13414 { } /* end */
13415};
13416/* Set mic1 nad line-in as output and mute mixer */
13417static struct hda_verb alc861_asus_ch6_init[] = {
13418 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13419 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13420 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13421 /* set pin widget 18h (mic1) for output (CLFE)*/
13422 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13423 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13424 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13425 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13426
13427 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13428#if 0
13429 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13430 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13431#endif
13432 { } /* end */
13433};
13434
13435static struct hda_channel_mode alc861_asus_modes[2] = {
13436 { 2, alc861_asus_ch2_init },
13437 { 6, alc861_asus_ch6_init },
13438};
13439
df694daa
KY
13440/* patch-ALC861 */
13441
13442static struct snd_kcontrol_new alc861_base_mixer[] = {
13443 /* output mixer control */
13444 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13445 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13446 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13447 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13448 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13449
13450 /*Input mixer control */
13451 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13452 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13453 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13454 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13455 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13456 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13458 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13461
df694daa
KY
13462 { } /* end */
13463};
13464
13465static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13466 /* output mixer control */
13467 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13468 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13469 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13470 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13471 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13472
13473 /* Input mixer control */
13474 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13475 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13476 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13477 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13478 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13479 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13481 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13484
df694daa
KY
13485 {
13486 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13487 .name = "Channel Mode",
13488 .info = alc_ch_mode_info,
13489 .get = alc_ch_mode_get,
13490 .put = alc_ch_mode_put,
13491 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13492 },
13493 { } /* end */
a53d1aec
TD
13494};
13495
d1d985f0 13496static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
13497 /* output mixer control */
13498 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13500 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 13501
a53d1aec 13502 { } /* end */
f12ab1e0 13503};
a53d1aec 13504
22309c3e
TI
13505static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13506 /* output mixer control */
13507 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13508 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13509 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13510 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13511 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13512
13513 /* Input mixer control */
13514 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13515 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13516 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13517 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13518 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13519 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13521 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13522 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13523 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13524
22309c3e
TI
13525 {
13526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13527 .name = "Channel Mode",
13528 .info = alc_ch_mode_info,
13529 .get = alc_ch_mode_get,
13530 .put = alc_ch_mode_put,
13531 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13532 },
13533 { } /* end */
f12ab1e0 13534};
7cdbff94
MD
13535
13536static struct snd_kcontrol_new alc861_asus_mixer[] = {
13537 /* output mixer control */
13538 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13539 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13540 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13541 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13542 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13543
13544 /* Input mixer control */
13545 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13546 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13547 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13548 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13549 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13550 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13552 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13553 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
13554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13555
7cdbff94
MD
13556 {
13557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13558 .name = "Channel Mode",
13559 .info = alc_ch_mode_info,
13560 .get = alc_ch_mode_get,
13561 .put = alc_ch_mode_put,
13562 .private_value = ARRAY_SIZE(alc861_asus_modes),
13563 },
13564 { }
56bb0cab
TI
13565};
13566
13567/* additional mixer */
d1d985f0 13568static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
13569 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13570 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
13571 { }
13572};
7cdbff94 13573
df694daa
KY
13574/*
13575 * generic initialization of ADC, input mixers and output mixers
13576 */
13577static struct hda_verb alc861_base_init_verbs[] = {
13578 /*
13579 * Unmute ADC0 and set the default input to mic-in
13580 */
13581 /* port-A for surround (rear panel) */
13582 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13583 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13584 /* port-B for mic-in (rear panel) with vref */
13585 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13586 /* port-C for line-in (rear panel) */
13587 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13588 /* port-D for Front */
13589 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13590 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13591 /* port-E for HP out (front panel) */
13592 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13593 /* route front PCM to HP */
9dece1d7 13594 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13595 /* port-F for mic-in (front panel) with vref */
13596 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13597 /* port-G for CLFE (rear panel) */
13598 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13599 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13600 /* port-H for side (rear panel) */
13601 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13602 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13603 /* CD-in */
13604 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13605 /* route front mic to ADC1*/
13606 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13607 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13608
df694daa
KY
13609 /* Unmute DAC0~3 & spdif out*/
13610 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13611 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13613 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13615
df694daa
KY
13616 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13617 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13618 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13619 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13620 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13621
df694daa
KY
13622 /* Unmute Stereo Mixer 15 */
13623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13627
13628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13630 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13631 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13636 /* hp used DAC 3 (Front) */
13637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13639
13640 { }
13641};
13642
13643static struct hda_verb alc861_threestack_init_verbs[] = {
13644 /*
13645 * Unmute ADC0 and set the default input to mic-in
13646 */
13647 /* port-A for surround (rear panel) */
13648 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13649 /* port-B for mic-in (rear panel) with vref */
13650 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13651 /* port-C for line-in (rear panel) */
13652 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13653 /* port-D for Front */
13654 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13655 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13656 /* port-E for HP out (front panel) */
13657 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13658 /* route front PCM to HP */
9dece1d7 13659 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13660 /* port-F for mic-in (front panel) with vref */
13661 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13662 /* port-G for CLFE (rear panel) */
13663 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13664 /* port-H for side (rear panel) */
13665 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13666 /* CD-in */
13667 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13668 /* route front mic to ADC1*/
13669 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13671 /* Unmute DAC0~3 & spdif out*/
13672 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13673 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13675 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13677
df694daa
KY
13678 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13679 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13680 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13681 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13682 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13683
df694daa
KY
13684 /* Unmute Stereo Mixer 15 */
13685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13689
13690 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13691 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13692 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13695 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13696 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13697 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13698 /* hp used DAC 3 (Front) */
13699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13701 { }
13702};
22309c3e
TI
13703
13704static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13705 /*
13706 * Unmute ADC0 and set the default input to mic-in
13707 */
13708 /* port-A for surround (rear panel) */
13709 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13710 /* port-B for mic-in (rear panel) with vref */
13711 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13712 /* port-C for line-in (rear panel) */
13713 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13714 /* port-D for Front */
13715 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13716 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13717 /* port-E for HP out (front panel) */
f12ab1e0
TI
13718 /* this has to be set to VREF80 */
13719 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 13720 /* route front PCM to HP */
9dece1d7 13721 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
13722 /* port-F for mic-in (front panel) with vref */
13723 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13724 /* port-G for CLFE (rear panel) */
13725 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13726 /* port-H for side (rear panel) */
13727 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13728 /* CD-in */
13729 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13730 /* route front mic to ADC1*/
13731 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13732 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13733 /* Unmute DAC0~3 & spdif out*/
13734 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13735 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13736 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13737 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13739
22309c3e
TI
13740 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13741 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13742 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13743 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13744 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13745
22309c3e
TI
13746 /* Unmute Stereo Mixer 15 */
13747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
13751
13752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13754 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13760 /* hp used DAC 3 (Front) */
13761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
13762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13763 { }
13764};
13765
7cdbff94
MD
13766static struct hda_verb alc861_asus_init_verbs[] = {
13767 /*
13768 * Unmute ADC0 and set the default input to mic-in
13769 */
f12ab1e0
TI
13770 /* port-A for surround (rear panel)
13771 * according to codec#0 this is the HP jack
13772 */
7cdbff94
MD
13773 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13774 /* route front PCM to HP */
13775 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13776 /* port-B for mic-in (rear panel) with vref */
13777 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13778 /* port-C for line-in (rear panel) */
13779 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13780 /* port-D for Front */
13781 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13782 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13783 /* port-E for HP out (front panel) */
f12ab1e0
TI
13784 /* this has to be set to VREF80 */
13785 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 13786 /* route front PCM to HP */
9dece1d7 13787 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
13788 /* port-F for mic-in (front panel) with vref */
13789 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13790 /* port-G for CLFE (rear panel) */
13791 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13792 /* port-H for side (rear panel) */
13793 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13794 /* CD-in */
13795 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13796 /* route front mic to ADC1*/
13797 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13798 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13799 /* Unmute DAC0~3 & spdif out*/
13800 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13801 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13802 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13803 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13805 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13806 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13807 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13808 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13809 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13810
7cdbff94
MD
13811 /* Unmute Stereo Mixer 15 */
13812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13816
13817 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13819 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13820 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13825 /* hp used DAC 3 (Front) */
13826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13828 { }
13829};
13830
56bb0cab
TI
13831/* additional init verbs for ASUS laptops */
13832static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13833 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13834 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13835 { }
13836};
7cdbff94 13837
df694daa
KY
13838/*
13839 * generic initialization of ADC, input mixers and output mixers
13840 */
13841static struct hda_verb alc861_auto_init_verbs[] = {
13842 /*
13843 * Unmute ADC0 and set the default input to mic-in
13844 */
f12ab1e0 13845 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13847
df694daa
KY
13848 /* Unmute DAC0~3 & spdif out*/
13849 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13850 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13851 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13852 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13854
df694daa
KY
13855 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13856 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13857 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13858 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13859 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13860
df694daa
KY
13861 /* Unmute Stereo Mixer 15 */
13862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13863 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13866
13867 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13868 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13870 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13874 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13875
13876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13880 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13882 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13883 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 13884
f12ab1e0 13885 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
13886
13887 { }
13888};
13889
a53d1aec
TD
13890static struct hda_verb alc861_toshiba_init_verbs[] = {
13891 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 13892
a53d1aec
TD
13893 { }
13894};
13895
13896/* toggle speaker-output according to the hp-jack state */
13897static void alc861_toshiba_automute(struct hda_codec *codec)
13898{
13899 unsigned int present;
13900
13901 present = snd_hda_codec_read(codec, 0x0f, 0,
13902 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13903 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13904 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13905 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13906 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
13907}
13908
13909static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13910 unsigned int res)
13911{
a53d1aec
TD
13912 if ((res >> 26) == ALC880_HP_EVENT)
13913 alc861_toshiba_automute(codec);
13914}
13915
df694daa
KY
13916/* pcm configuration: identiacal with ALC880 */
13917#define alc861_pcm_analog_playback alc880_pcm_analog_playback
13918#define alc861_pcm_analog_capture alc880_pcm_analog_capture
13919#define alc861_pcm_digital_playback alc880_pcm_digital_playback
13920#define alc861_pcm_digital_capture alc880_pcm_digital_capture
13921
13922
13923#define ALC861_DIGOUT_NID 0x07
13924
13925static struct hda_channel_mode alc861_8ch_modes[1] = {
13926 { 8, NULL }
13927};
13928
13929static hda_nid_t alc861_dac_nids[4] = {
13930 /* front, surround, clfe, side */
13931 0x03, 0x06, 0x05, 0x04
13932};
13933
9c7f852e
TI
13934static hda_nid_t alc660_dac_nids[3] = {
13935 /* front, clfe, surround */
13936 0x03, 0x05, 0x06
13937};
13938
df694daa
KY
13939static hda_nid_t alc861_adc_nids[1] = {
13940 /* ADC0-2 */
13941 0x08,
13942};
13943
13944static struct hda_input_mux alc861_capture_source = {
13945 .num_items = 5,
13946 .items = {
13947 { "Mic", 0x0 },
13948 { "Front Mic", 0x3 },
13949 { "Line", 0x1 },
13950 { "CD", 0x4 },
13951 { "Mixer", 0x5 },
13952 },
13953};
13954
13955/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
13956static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13957 const struct auto_pin_cfg *cfg)
df694daa
KY
13958{
13959 int i;
13960 hda_nid_t nid;
13961
13962 spec->multiout.dac_nids = spec->private_dac_nids;
13963 for (i = 0; i < cfg->line_outs; i++) {
13964 nid = cfg->line_out_pins[i];
13965 if (nid) {
13966 if (i >= ARRAY_SIZE(alc861_dac_nids))
13967 continue;
13968 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13969 }
13970 }
13971 spec->multiout.num_dacs = cfg->line_outs;
13972 return 0;
13973}
13974
13975/* add playback controls from the parsed DAC table */
13976static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13977 const struct auto_pin_cfg *cfg)
13978{
13979 char name[32];
f12ab1e0
TI
13980 static const char *chname[4] = {
13981 "Front", "Surround", NULL /*CLFE*/, "Side"
13982 };
df694daa
KY
13983 hda_nid_t nid;
13984 int i, idx, err;
13985
13986 for (i = 0; i < cfg->line_outs; i++) {
13987 nid = spec->multiout.dac_nids[i];
f12ab1e0 13988 if (!nid)
df694daa
KY
13989 continue;
13990 if (nid == 0x05) {
13991 /* Center/LFE */
f12ab1e0
TI
13992 err = add_control(spec, ALC_CTL_BIND_MUTE,
13993 "Center Playback Switch",
13994 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13995 HDA_OUTPUT));
13996 if (err < 0)
df694daa 13997 return err;
f12ab1e0
TI
13998 err = add_control(spec, ALC_CTL_BIND_MUTE,
13999 "LFE Playback Switch",
14000 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14001 HDA_OUTPUT));
14002 if (err < 0)
df694daa
KY
14003 return err;
14004 } else {
f12ab1e0
TI
14005 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
14006 idx++)
df694daa
KY
14007 if (nid == alc861_dac_nids[idx])
14008 break;
14009 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
14010 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14011 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14012 HDA_OUTPUT));
14013 if (err < 0)
df694daa
KY
14014 return err;
14015 }
14016 }
14017 return 0;
14018}
14019
14020static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
14021{
14022 int err;
14023 hda_nid_t nid;
14024
f12ab1e0 14025 if (!pin)
df694daa
KY
14026 return 0;
14027
14028 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14029 nid = 0x03;
f12ab1e0
TI
14030 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
14031 "Headphone Playback Switch",
14032 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
14033 if (err < 0)
df694daa
KY
14034 return err;
14035 spec->multiout.hp_nid = nid;
14036 }
14037 return 0;
14038}
14039
14040/* create playback/capture controls for input pins */
f12ab1e0
TI
14041static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
14042 const struct auto_pin_cfg *cfg)
df694daa 14043{
61b9b9b1 14044 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
14045 int i, err, idx, idx1;
14046
14047 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 14048 switch (cfg->input_pins[i]) {
df694daa
KY
14049 case 0x0c:
14050 idx1 = 1;
f12ab1e0 14051 idx = 2; /* Line In */
df694daa
KY
14052 break;
14053 case 0x0f:
14054 idx1 = 2;
f12ab1e0 14055 idx = 2; /* Line In */
df694daa
KY
14056 break;
14057 case 0x0d:
14058 idx1 = 0;
f12ab1e0 14059 idx = 1; /* Mic In */
df694daa 14060 break;
f12ab1e0 14061 case 0x10:
df694daa 14062 idx1 = 3;
f12ab1e0 14063 idx = 1; /* Mic In */
df694daa
KY
14064 break;
14065 case 0x11:
14066 idx1 = 4;
f12ab1e0 14067 idx = 0; /* CD */
df694daa
KY
14068 break;
14069 default:
14070 continue;
14071 }
14072
4a471b7d
TI
14073 err = new_analog_input(spec, cfg->input_pins[i],
14074 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
14075 if (err < 0)
14076 return err;
14077
4a471b7d 14078 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 14079 imux->items[imux->num_items].index = idx1;
f12ab1e0 14080 imux->num_items++;
df694daa
KY
14081 }
14082 return 0;
14083}
14084
f12ab1e0
TI
14085static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14086 hda_nid_t nid,
df694daa
KY
14087 int pin_type, int dac_idx)
14088{
564c5bea
JL
14089 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14090 pin_type);
14091 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14092 AMP_OUT_UNMUTE);
df694daa
KY
14093}
14094
14095static void alc861_auto_init_multi_out(struct hda_codec *codec)
14096{
14097 struct alc_spec *spec = codec->spec;
14098 int i;
14099
14100 for (i = 0; i < spec->autocfg.line_outs; i++) {
14101 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14102 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 14103 if (nid)
baba8ee9 14104 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 14105 spec->multiout.dac_nids[i]);
df694daa
KY
14106 }
14107}
14108
14109static void alc861_auto_init_hp_out(struct hda_codec *codec)
14110{
14111 struct alc_spec *spec = codec->spec;
14112 hda_nid_t pin;
14113
eb06ed8f 14114 pin = spec->autocfg.hp_pins[0];
df694daa 14115 if (pin) /* connect to front */
f12ab1e0
TI
14116 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
14117 spec->multiout.dac_nids[0]);
f6c7e546
TI
14118 pin = spec->autocfg.speaker_pins[0];
14119 if (pin)
14120 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
14121}
14122
14123static void alc861_auto_init_analog_input(struct hda_codec *codec)
14124{
14125 struct alc_spec *spec = codec->spec;
14126 int i;
14127
14128 for (i = 0; i < AUTO_PIN_LAST; i++) {
14129 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
14130 if (nid >= 0x0c && nid <= 0x11)
14131 alc_set_input_pin(codec, nid, i);
df694daa
KY
14132 }
14133}
14134
14135/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
14136/* return 1 if successful, 0 if the proper config is not found,
14137 * or a negative error code
14138 */
df694daa
KY
14139static int alc861_parse_auto_config(struct hda_codec *codec)
14140{
14141 struct alc_spec *spec = codec->spec;
14142 int err;
14143 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14144
f12ab1e0
TI
14145 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14146 alc861_ignore);
14147 if (err < 0)
df694daa 14148 return err;
f12ab1e0 14149 if (!spec->autocfg.line_outs)
df694daa
KY
14150 return 0; /* can't find valid BIOS pin config */
14151
f12ab1e0
TI
14152 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
14153 if (err < 0)
14154 return err;
14155 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
14156 if (err < 0)
14157 return err;
14158 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
14159 if (err < 0)
14160 return err;
14161 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
14162 if (err < 0)
df694daa
KY
14163 return err;
14164
14165 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14166
0852d7a6 14167 if (spec->autocfg.dig_outs)
df694daa
KY
14168 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14169
603c4019 14170 if (spec->kctls.list)
d88897ea 14171 add_mixer(spec, spec->kctls.list);
df694daa 14172
d88897ea 14173 add_verb(spec, alc861_auto_init_verbs);
df694daa 14174
a1e8d2da 14175 spec->num_mux_defs = 1;
61b9b9b1 14176 spec->input_mux = &spec->private_imux[0];
df694daa
KY
14177
14178 spec->adc_nids = alc861_adc_nids;
14179 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
f9e336f6 14180 set_capture_mixer(spec);
df694daa 14181
4a79ba34
TI
14182 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14183
df694daa
KY
14184 return 1;
14185}
14186
ae6b813a
TI
14187/* additional initialization for auto-configuration model */
14188static void alc861_auto_init(struct hda_codec *codec)
df694daa 14189{
f6c7e546 14190 struct alc_spec *spec = codec->spec;
df694daa
KY
14191 alc861_auto_init_multi_out(codec);
14192 alc861_auto_init_hp_out(codec);
14193 alc861_auto_init_analog_input(codec);
f6c7e546 14194 if (spec->unsol_event)
7fb0d78f 14195 alc_inithook(codec);
df694daa
KY
14196}
14197
cb53c626
TI
14198#ifdef CONFIG_SND_HDA_POWER_SAVE
14199static struct hda_amp_list alc861_loopbacks[] = {
14200 { 0x15, HDA_INPUT, 0 },
14201 { 0x15, HDA_INPUT, 1 },
14202 { 0x15, HDA_INPUT, 2 },
14203 { 0x15, HDA_INPUT, 3 },
14204 { } /* end */
14205};
14206#endif
14207
df694daa
KY
14208
14209/*
14210 * configuration and preset
14211 */
f5fcc13c
TI
14212static const char *alc861_models[ALC861_MODEL_LAST] = {
14213 [ALC861_3ST] = "3stack",
14214 [ALC660_3ST] = "3stack-660",
14215 [ALC861_3ST_DIG] = "3stack-dig",
14216 [ALC861_6ST_DIG] = "6stack-dig",
14217 [ALC861_UNIWILL_M31] = "uniwill-m31",
14218 [ALC861_TOSHIBA] = "toshiba",
14219 [ALC861_ASUS] = "asus",
14220 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14221 [ALC861_AUTO] = "auto",
14222};
14223
14224static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 14225 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
14226 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14227 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14228 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 14229 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 14230 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 14231 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
14232 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14233 * Any other models that need this preset?
14234 */
14235 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
14236 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14237 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 14238 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
14239 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14240 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14241 /* FIXME: the below seems conflict */
14242 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 14243 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 14244 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
14245 {}
14246};
14247
14248static struct alc_config_preset alc861_presets[] = {
14249 [ALC861_3ST] = {
14250 .mixers = { alc861_3ST_mixer },
14251 .init_verbs = { alc861_threestack_init_verbs },
14252 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14253 .dac_nids = alc861_dac_nids,
14254 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14255 .channel_mode = alc861_threestack_modes,
4e195a7b 14256 .need_dac_fix = 1,
df694daa
KY
14257 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14258 .adc_nids = alc861_adc_nids,
14259 .input_mux = &alc861_capture_source,
14260 },
14261 [ALC861_3ST_DIG] = {
14262 .mixers = { alc861_base_mixer },
14263 .init_verbs = { alc861_threestack_init_verbs },
14264 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14265 .dac_nids = alc861_dac_nids,
14266 .dig_out_nid = ALC861_DIGOUT_NID,
14267 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14268 .channel_mode = alc861_threestack_modes,
4e195a7b 14269 .need_dac_fix = 1,
df694daa
KY
14270 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14271 .adc_nids = alc861_adc_nids,
14272 .input_mux = &alc861_capture_source,
14273 },
14274 [ALC861_6ST_DIG] = {
14275 .mixers = { alc861_base_mixer },
14276 .init_verbs = { alc861_base_init_verbs },
14277 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14278 .dac_nids = alc861_dac_nids,
14279 .dig_out_nid = ALC861_DIGOUT_NID,
14280 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14281 .channel_mode = alc861_8ch_modes,
14282 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14283 .adc_nids = alc861_adc_nids,
14284 .input_mux = &alc861_capture_source,
14285 },
9c7f852e
TI
14286 [ALC660_3ST] = {
14287 .mixers = { alc861_3ST_mixer },
14288 .init_verbs = { alc861_threestack_init_verbs },
14289 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14290 .dac_nids = alc660_dac_nids,
14291 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14292 .channel_mode = alc861_threestack_modes,
4e195a7b 14293 .need_dac_fix = 1,
9c7f852e
TI
14294 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14295 .adc_nids = alc861_adc_nids,
14296 .input_mux = &alc861_capture_source,
14297 },
22309c3e
TI
14298 [ALC861_UNIWILL_M31] = {
14299 .mixers = { alc861_uniwill_m31_mixer },
14300 .init_verbs = { alc861_uniwill_m31_init_verbs },
14301 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14302 .dac_nids = alc861_dac_nids,
14303 .dig_out_nid = ALC861_DIGOUT_NID,
14304 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14305 .channel_mode = alc861_uniwill_m31_modes,
14306 .need_dac_fix = 1,
14307 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14308 .adc_nids = alc861_adc_nids,
14309 .input_mux = &alc861_capture_source,
14310 },
a53d1aec
TD
14311 [ALC861_TOSHIBA] = {
14312 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
14313 .init_verbs = { alc861_base_init_verbs,
14314 alc861_toshiba_init_verbs },
a53d1aec
TD
14315 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14316 .dac_nids = alc861_dac_nids,
14317 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14318 .channel_mode = alc883_3ST_2ch_modes,
14319 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14320 .adc_nids = alc861_adc_nids,
14321 .input_mux = &alc861_capture_source,
14322 .unsol_event = alc861_toshiba_unsol_event,
14323 .init_hook = alc861_toshiba_automute,
14324 },
7cdbff94
MD
14325 [ALC861_ASUS] = {
14326 .mixers = { alc861_asus_mixer },
14327 .init_verbs = { alc861_asus_init_verbs },
14328 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14329 .dac_nids = alc861_dac_nids,
14330 .dig_out_nid = ALC861_DIGOUT_NID,
14331 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14332 .channel_mode = alc861_asus_modes,
14333 .need_dac_fix = 1,
14334 .hp_nid = 0x06,
14335 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14336 .adc_nids = alc861_adc_nids,
14337 .input_mux = &alc861_capture_source,
14338 },
56bb0cab
TI
14339 [ALC861_ASUS_LAPTOP] = {
14340 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14341 .init_verbs = { alc861_asus_init_verbs,
14342 alc861_asus_laptop_init_verbs },
14343 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14344 .dac_nids = alc861_dac_nids,
14345 .dig_out_nid = ALC861_DIGOUT_NID,
14346 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14347 .channel_mode = alc883_3ST_2ch_modes,
14348 .need_dac_fix = 1,
14349 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14350 .adc_nids = alc861_adc_nids,
14351 .input_mux = &alc861_capture_source,
14352 },
14353};
df694daa
KY
14354
14355
14356static int patch_alc861(struct hda_codec *codec)
14357{
14358 struct alc_spec *spec;
14359 int board_config;
14360 int err;
14361
dc041e0b 14362 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
14363 if (spec == NULL)
14364 return -ENOMEM;
14365
f12ab1e0 14366 codec->spec = spec;
df694daa 14367
f5fcc13c
TI
14368 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14369 alc861_models,
14370 alc861_cfg_tbl);
9c7f852e 14371
f5fcc13c 14372 if (board_config < 0) {
6c627f39
TI
14373 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14374 "trying auto-probe from BIOS...\n", codec->chip_name);
df694daa
KY
14375 board_config = ALC861_AUTO;
14376 }
14377
14378 if (board_config == ALC861_AUTO) {
14379 /* automatic parse from the BIOS config */
14380 err = alc861_parse_auto_config(codec);
14381 if (err < 0) {
14382 alc_free(codec);
14383 return err;
f12ab1e0 14384 } else if (!err) {
9c7f852e
TI
14385 printk(KERN_INFO
14386 "hda_codec: Cannot set up configuration "
14387 "from BIOS. Using base mode...\n");
df694daa
KY
14388 board_config = ALC861_3ST_DIG;
14389 }
14390 }
14391
680cd536
KK
14392 err = snd_hda_attach_beep_device(codec, 0x23);
14393 if (err < 0) {
14394 alc_free(codec);
14395 return err;
14396 }
14397
df694daa
KY
14398 if (board_config != ALC861_AUTO)
14399 setup_preset(spec, &alc861_presets[board_config]);
14400
df694daa
KY
14401 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14402 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14403
df694daa
KY
14404 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14405 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14406
45bdd1c1
TI
14407 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14408
2134ea4f
TI
14409 spec->vmaster_nid = 0x03;
14410
df694daa
KY
14411 codec->patch_ops = alc_patch_ops;
14412 if (board_config == ALC861_AUTO)
ae6b813a 14413 spec->init_hook = alc861_auto_init;
cb53c626
TI
14414#ifdef CONFIG_SND_HDA_POWER_SAVE
14415 if (!spec->loopback.amplist)
14416 spec->loopback.amplist = alc861_loopbacks;
14417#endif
daead538 14418 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 14419
1da177e4
LT
14420 return 0;
14421}
14422
f32610ed
JS
14423/*
14424 * ALC861-VD support
14425 *
14426 * Based on ALC882
14427 *
14428 * In addition, an independent DAC
14429 */
14430#define ALC861VD_DIGOUT_NID 0x06
14431
14432static hda_nid_t alc861vd_dac_nids[4] = {
14433 /* front, surr, clfe, side surr */
14434 0x02, 0x03, 0x04, 0x05
14435};
14436
14437/* dac_nids for ALC660vd are in a different order - according to
14438 * Realtek's driver.
14439 * This should probably tesult in a different mixer for 6stack models
14440 * of ALC660vd codecs, but for now there is only 3stack mixer
14441 * - and it is the same as in 861vd.
14442 * adc_nids in ALC660vd are (is) the same as in 861vd
14443 */
14444static hda_nid_t alc660vd_dac_nids[3] = {
14445 /* front, rear, clfe, rear_surr */
14446 0x02, 0x04, 0x03
14447};
14448
14449static hda_nid_t alc861vd_adc_nids[1] = {
14450 /* ADC0 */
14451 0x09,
14452};
14453
e1406348
TI
14454static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14455
f32610ed
JS
14456/* input MUX */
14457/* FIXME: should be a matrix-type input source selection */
14458static struct hda_input_mux alc861vd_capture_source = {
14459 .num_items = 4,
14460 .items = {
14461 { "Mic", 0x0 },
14462 { "Front Mic", 0x1 },
14463 { "Line", 0x2 },
14464 { "CD", 0x4 },
14465 },
14466};
14467
272a527c 14468static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 14469 .num_items = 2,
272a527c 14470 .items = {
b419f346
TD
14471 { "Ext Mic", 0x0 },
14472 { "Int Mic", 0x1 },
272a527c
KY
14473 },
14474};
14475
d1a991a6
KY
14476static struct hda_input_mux alc861vd_hp_capture_source = {
14477 .num_items = 2,
14478 .items = {
14479 { "Front Mic", 0x0 },
14480 { "ATAPI Mic", 0x1 },
14481 },
14482};
14483
f32610ed
JS
14484/*
14485 * 2ch mode
14486 */
14487static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14488 { 2, NULL }
14489};
14490
14491/*
14492 * 6ch mode
14493 */
14494static struct hda_verb alc861vd_6stack_ch6_init[] = {
14495 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14496 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14497 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14498 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14499 { } /* end */
14500};
14501
14502/*
14503 * 8ch mode
14504 */
14505static struct hda_verb alc861vd_6stack_ch8_init[] = {
14506 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14507 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14508 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14509 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14510 { } /* end */
14511};
14512
14513static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14514 { 6, alc861vd_6stack_ch6_init },
14515 { 8, alc861vd_6stack_ch8_init },
14516};
14517
14518static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14519 {
14520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14521 .name = "Channel Mode",
14522 .info = alc_ch_mode_info,
14523 .get = alc_ch_mode_get,
14524 .put = alc_ch_mode_put,
14525 },
14526 { } /* end */
14527};
14528
f32610ed
JS
14529/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14530 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14531 */
14532static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14533 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14534 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14535
14536 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14537 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14538
14539 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14540 HDA_OUTPUT),
14541 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14542 HDA_OUTPUT),
14543 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14544 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14545
14546 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14547 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14548
14549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14550
14551 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14553 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14554
14555 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14558
14559 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14560 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14561
14562 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14563 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14564
f32610ed
JS
14565 { } /* end */
14566};
14567
14568static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14569 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14570 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14571
14572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14573
14574 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14577
14578 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14581
14582 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14583 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14584
14585 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14586 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14587
f32610ed
JS
14588 { } /* end */
14589};
14590
bdd148a3
KY
14591static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14592 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14593 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14594 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14595
14596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14597
14598 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14600 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14601
14602 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14605
14606 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14607 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14608
14609 { } /* end */
14610};
14611
b419f346
TD
14612/* Pin assignment: Speaker=0x14, HP = 0x15,
14613 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
14614 */
14615static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
14616 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14617 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
14618 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14619 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
14620 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14621 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14622 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14623 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14624 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14625 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
14626 { } /* end */
14627};
14628
d1a991a6
KY
14629/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14630 * Front Mic=0x18, ATAPI Mic = 0x19,
14631 */
14632static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14633 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14634 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14636 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14637 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14638 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14639 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14640 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 14641
d1a991a6
KY
14642 { } /* end */
14643};
14644
f32610ed
JS
14645/*
14646 * generic initialization of ADC, input mixers and output mixers
14647 */
14648static struct hda_verb alc861vd_volume_init_verbs[] = {
14649 /*
14650 * Unmute ADC0 and set the default input to mic-in
14651 */
14652 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14654
14655 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14656 * the analog-loopback mixer widget
14657 */
14658 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14659 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14660 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14661 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14662 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14663 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
14664
14665 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
14666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 14669 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
14670
14671 /*
14672 * Set up output mixers (0x02 - 0x05)
14673 */
14674 /* set vol=0 to output mixers */
14675 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14676 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14677 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14678 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14679
14680 /* set up input amps for analog loopback */
14681 /* Amp Indices: DAC = 0, mixer = 1 */
14682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14684 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14686 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14688 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14689 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14690
14691 { }
14692};
14693
14694/*
14695 * 3-stack pin configuration:
14696 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14697 */
14698static struct hda_verb alc861vd_3stack_init_verbs[] = {
14699 /*
14700 * Set pin mode and muting
14701 */
14702 /* set front pin widgets 0x14 for output */
14703 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14704 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14705 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14706
14707 /* Mic (rear) pin: input vref at 80% */
14708 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14710 /* Front Mic pin: input vref at 80% */
14711 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14712 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14713 /* Line In pin: input */
14714 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14715 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14716 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14717 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14718 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14719 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14720 /* CD pin widget for input */
14721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14722
14723 { }
14724};
14725
14726/*
14727 * 6-stack pin configuration:
14728 */
14729static struct hda_verb alc861vd_6stack_init_verbs[] = {
14730 /*
14731 * Set pin mode and muting
14732 */
14733 /* set front pin widgets 0x14 for output */
14734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14735 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14736 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14737
14738 /* Rear Pin: output 1 (0x0d) */
14739 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14740 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14741 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14742 /* CLFE Pin: output 2 (0x0e) */
14743 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14744 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14745 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14746 /* Side Pin: output 3 (0x0f) */
14747 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14748 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14749 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14750
14751 /* Mic (rear) pin: input vref at 80% */
14752 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14753 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14754 /* Front Mic pin: input vref at 80% */
14755 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14756 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14757 /* Line In pin: input */
14758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14760 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14761 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14762 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14763 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14764 /* CD pin widget for input */
14765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14766
14767 { }
14768};
14769
bdd148a3
KY
14770static struct hda_verb alc861vd_eapd_verbs[] = {
14771 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14772 { }
14773};
14774
f9423e7a
KY
14775static struct hda_verb alc660vd_eapd_verbs[] = {
14776 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14777 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14778 { }
14779};
14780
bdd148a3
KY
14781static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14784 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14785 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14786 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14787 {}
14788};
14789
bdd148a3
KY
14790static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14791{
14792 unsigned int present;
14793 unsigned char bits;
14794
14795 present = snd_hda_codec_read(codec, 0x18, 0,
14796 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14797 bits = present ? HDA_AMP_MUTE : 0;
14798 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14799 HDA_AMP_MUTE, bits);
bdd148a3
KY
14800}
14801
a9fd4f3f 14802static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
bdd148a3 14803{
a9fd4f3f
TI
14804 struct alc_spec *spec = codec->spec;
14805
14806 spec->autocfg.hp_pins[0] = 0x1b;
14807 spec->autocfg.speaker_pins[0] = 0x14;
14808 alc_automute_amp(codec);
bdd148a3
KY
14809 alc861vd_lenovo_mic_automute(codec);
14810}
14811
14812static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14813 unsigned int res)
14814{
14815 switch (res >> 26) {
bdd148a3
KY
14816 case ALC880_MIC_EVENT:
14817 alc861vd_lenovo_mic_automute(codec);
14818 break;
a9fd4f3f
TI
14819 default:
14820 alc_automute_amp_unsol_event(codec, res);
14821 break;
bdd148a3
KY
14822 }
14823}
14824
272a527c
KY
14825static struct hda_verb alc861vd_dallas_verbs[] = {
14826 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14827 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14828 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14829 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14830
14831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14833 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14834 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14835 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14836 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14837 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14838 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14839
272a527c
KY
14840 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14841 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14842 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14844 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14845 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14846 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14847 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14848
14849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14850 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14851 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14852 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14853 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14854 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14855 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14856 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14857
14858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14862
14863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 14864 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
14865 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14866
14867 { } /* end */
14868};
14869
14870/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 14871static void alc861vd_dallas_init_hook(struct hda_codec *codec)
272a527c 14872{
a9fd4f3f 14873 struct alc_spec *spec = codec->spec;
272a527c 14874
a9fd4f3f
TI
14875 spec->autocfg.hp_pins[0] = 0x15;
14876 spec->autocfg.speaker_pins[0] = 0x14;
14877 alc_automute_amp(codec);
272a527c
KY
14878}
14879
cb53c626
TI
14880#ifdef CONFIG_SND_HDA_POWER_SAVE
14881#define alc861vd_loopbacks alc880_loopbacks
14882#endif
14883
f32610ed
JS
14884/* pcm configuration: identiacal with ALC880 */
14885#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14886#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14887#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14888#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14889
14890/*
14891 * configuration and preset
14892 */
14893static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14894 [ALC660VD_3ST] = "3stack-660",
983f8ae4 14895 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 14896 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
14897 [ALC861VD_3ST] = "3stack",
14898 [ALC861VD_3ST_DIG] = "3stack-digout",
14899 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 14900 [ALC861VD_LENOVO] = "lenovo",
272a527c 14901 [ALC861VD_DALLAS] = "dallas",
983f8ae4 14902 [ALC861VD_HP] = "hp",
f32610ed
JS
14903 [ALC861VD_AUTO] = "auto",
14904};
14905
14906static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
14907 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14908 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 14909 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 14910 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13c94744 14911 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 14912 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 14913 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 14914 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 14915 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 14916 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 14917 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 14918 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 14919 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 14920 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 14921 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
14922 {}
14923};
14924
14925static struct alc_config_preset alc861vd_presets[] = {
14926 [ALC660VD_3ST] = {
14927 .mixers = { alc861vd_3st_mixer },
14928 .init_verbs = { alc861vd_volume_init_verbs,
14929 alc861vd_3stack_init_verbs },
14930 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14931 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14932 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14933 .channel_mode = alc861vd_3stack_2ch_modes,
14934 .input_mux = &alc861vd_capture_source,
14935 },
6963f84c
MC
14936 [ALC660VD_3ST_DIG] = {
14937 .mixers = { alc861vd_3st_mixer },
14938 .init_verbs = { alc861vd_volume_init_verbs,
14939 alc861vd_3stack_init_verbs },
14940 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14941 .dac_nids = alc660vd_dac_nids,
14942 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14943 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14944 .channel_mode = alc861vd_3stack_2ch_modes,
14945 .input_mux = &alc861vd_capture_source,
14946 },
f32610ed
JS
14947 [ALC861VD_3ST] = {
14948 .mixers = { alc861vd_3st_mixer },
14949 .init_verbs = { alc861vd_volume_init_verbs,
14950 alc861vd_3stack_init_verbs },
14951 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14952 .dac_nids = alc861vd_dac_nids,
14953 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14954 .channel_mode = alc861vd_3stack_2ch_modes,
14955 .input_mux = &alc861vd_capture_source,
14956 },
14957 [ALC861VD_3ST_DIG] = {
14958 .mixers = { alc861vd_3st_mixer },
14959 .init_verbs = { alc861vd_volume_init_verbs,
14960 alc861vd_3stack_init_verbs },
14961 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14962 .dac_nids = alc861vd_dac_nids,
14963 .dig_out_nid = ALC861VD_DIGOUT_NID,
14964 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14965 .channel_mode = alc861vd_3stack_2ch_modes,
14966 .input_mux = &alc861vd_capture_source,
14967 },
14968 [ALC861VD_6ST_DIG] = {
14969 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14970 .init_verbs = { alc861vd_volume_init_verbs,
14971 alc861vd_6stack_init_verbs },
14972 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14973 .dac_nids = alc861vd_dac_nids,
14974 .dig_out_nid = ALC861VD_DIGOUT_NID,
14975 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14976 .channel_mode = alc861vd_6stack_modes,
14977 .input_mux = &alc861vd_capture_source,
14978 },
bdd148a3
KY
14979 [ALC861VD_LENOVO] = {
14980 .mixers = { alc861vd_lenovo_mixer },
14981 .init_verbs = { alc861vd_volume_init_verbs,
14982 alc861vd_3stack_init_verbs,
14983 alc861vd_eapd_verbs,
14984 alc861vd_lenovo_unsol_verbs },
14985 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14986 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14987 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14988 .channel_mode = alc861vd_3stack_2ch_modes,
14989 .input_mux = &alc861vd_capture_source,
14990 .unsol_event = alc861vd_lenovo_unsol_event,
a9fd4f3f 14991 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 14992 },
272a527c
KY
14993 [ALC861VD_DALLAS] = {
14994 .mixers = { alc861vd_dallas_mixer },
14995 .init_verbs = { alc861vd_dallas_verbs },
14996 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14997 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14998 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14999 .channel_mode = alc861vd_3stack_2ch_modes,
15000 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f
TI
15001 .unsol_event = alc_automute_amp_unsol_event,
15002 .init_hook = alc861vd_dallas_init_hook,
d1a991a6
KY
15003 },
15004 [ALC861VD_HP] = {
15005 .mixers = { alc861vd_hp_mixer },
15006 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15007 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15008 .dac_nids = alc861vd_dac_nids,
d1a991a6 15009 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
15010 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15011 .channel_mode = alc861vd_3stack_2ch_modes,
15012 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f
TI
15013 .unsol_event = alc_automute_amp_unsol_event,
15014 .init_hook = alc861vd_dallas_init_hook,
ea1fb29a 15015 },
13c94744
TI
15016 [ALC660VD_ASUS_V1S] = {
15017 .mixers = { alc861vd_lenovo_mixer },
15018 .init_verbs = { alc861vd_volume_init_verbs,
15019 alc861vd_3stack_init_verbs,
15020 alc861vd_eapd_verbs,
15021 alc861vd_lenovo_unsol_verbs },
15022 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15023 .dac_nids = alc660vd_dac_nids,
15024 .dig_out_nid = ALC861VD_DIGOUT_NID,
15025 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15026 .channel_mode = alc861vd_3stack_2ch_modes,
15027 .input_mux = &alc861vd_capture_source,
15028 .unsol_event = alc861vd_lenovo_unsol_event,
a9fd4f3f 15029 .init_hook = alc861vd_lenovo_init_hook,
13c94744 15030 },
f32610ed
JS
15031};
15032
15033/*
15034 * BIOS auto configuration
15035 */
15036static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15037 hda_nid_t nid, int pin_type, int dac_idx)
15038{
f6c7e546 15039 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
15040}
15041
15042static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15043{
15044 struct alc_spec *spec = codec->spec;
15045 int i;
15046
15047 for (i = 0; i <= HDA_SIDE; i++) {
15048 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15049 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
15050 if (nid)
15051 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 15052 pin_type, i);
f32610ed
JS
15053 }
15054}
15055
15056
15057static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15058{
15059 struct alc_spec *spec = codec->spec;
15060 hda_nid_t pin;
15061
15062 pin = spec->autocfg.hp_pins[0];
15063 if (pin) /* connect to front and use dac 0 */
15064 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
15065 pin = spec->autocfg.speaker_pins[0];
15066 if (pin)
15067 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
15068}
15069
15070#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
15071#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15072
15073static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15074{
15075 struct alc_spec *spec = codec->spec;
15076 int i;
15077
15078 for (i = 0; i < AUTO_PIN_LAST; i++) {
15079 hda_nid_t nid = spec->autocfg.input_pins[i];
15080 if (alc861vd_is_input_pin(nid)) {
23f0c048 15081 alc_set_input_pin(codec, nid, i);
e82c025b
TI
15082 if (nid != ALC861VD_PIN_CD_NID &&
15083 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
15084 snd_hda_codec_write(codec, nid, 0,
15085 AC_VERB_SET_AMP_GAIN_MUTE,
15086 AMP_OUT_MUTE);
15087 }
15088 }
15089}
15090
f511b01c
TI
15091#define alc861vd_auto_init_input_src alc882_auto_init_input_src
15092
f32610ed
JS
15093#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15094#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15095
15096/* add playback controls from the parsed DAC table */
15097/* Based on ALC880 version. But ALC861VD has separate,
15098 * different NIDs for mute/unmute switch and volume control */
15099static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15100 const struct auto_pin_cfg *cfg)
15101{
15102 char name[32];
15103 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15104 hda_nid_t nid_v, nid_s;
15105 int i, err;
15106
15107 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 15108 if (!spec->multiout.dac_nids[i])
f32610ed
JS
15109 continue;
15110 nid_v = alc861vd_idx_to_mixer_vol(
15111 alc880_dac_to_idx(
15112 spec->multiout.dac_nids[i]));
15113 nid_s = alc861vd_idx_to_mixer_switch(
15114 alc880_dac_to_idx(
15115 spec->multiout.dac_nids[i]));
15116
15117 if (i == 2) {
15118 /* Center/LFE */
f12ab1e0
TI
15119 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15120 "Center Playback Volume",
15121 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15122 HDA_OUTPUT));
15123 if (err < 0)
f32610ed 15124 return err;
f12ab1e0
TI
15125 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15126 "LFE Playback Volume",
15127 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15128 HDA_OUTPUT));
15129 if (err < 0)
f32610ed 15130 return err;
f12ab1e0
TI
15131 err = add_control(spec, ALC_CTL_BIND_MUTE,
15132 "Center Playback Switch",
15133 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15134 HDA_INPUT));
15135 if (err < 0)
f32610ed 15136 return err;
f12ab1e0
TI
15137 err = add_control(spec, ALC_CTL_BIND_MUTE,
15138 "LFE Playback Switch",
15139 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15140 HDA_INPUT));
15141 if (err < 0)
f32610ed
JS
15142 return err;
15143 } else {
15144 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
15145 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15146 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15147 HDA_OUTPUT));
15148 if (err < 0)
f32610ed
JS
15149 return err;
15150 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 15151 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 15152 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
15153 HDA_INPUT));
15154 if (err < 0)
f32610ed
JS
15155 return err;
15156 }
15157 }
15158 return 0;
15159}
15160
15161/* add playback controls for speaker and HP outputs */
15162/* Based on ALC880 version. But ALC861VD has separate,
15163 * different NIDs for mute/unmute switch and volume control */
15164static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15165 hda_nid_t pin, const char *pfx)
15166{
15167 hda_nid_t nid_v, nid_s;
15168 int err;
15169 char name[32];
15170
f12ab1e0 15171 if (!pin)
f32610ed
JS
15172 return 0;
15173
15174 if (alc880_is_fixed_pin(pin)) {
15175 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15176 /* specify the DAC as the extra output */
f12ab1e0 15177 if (!spec->multiout.hp_nid)
f32610ed
JS
15178 spec->multiout.hp_nid = nid_v;
15179 else
15180 spec->multiout.extra_out_nid[0] = nid_v;
15181 /* control HP volume/switch on the output mixer amp */
15182 nid_v = alc861vd_idx_to_mixer_vol(
15183 alc880_fixed_pin_idx(pin));
15184 nid_s = alc861vd_idx_to_mixer_switch(
15185 alc880_fixed_pin_idx(pin));
15186
15187 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
15188 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15189 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15190 if (err < 0)
f32610ed
JS
15191 return err;
15192 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
15193 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15194 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15195 if (err < 0)
f32610ed
JS
15196 return err;
15197 } else if (alc880_is_multi_pin(pin)) {
15198 /* set manual connection */
15199 /* we have only a switch on HP-out PIN */
15200 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
15201 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15202 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15203 if (err < 0)
f32610ed
JS
15204 return err;
15205 }
15206 return 0;
15207}
15208
15209/* parse the BIOS configuration and set up the alc_spec
15210 * return 1 if successful, 0 if the proper config is not found,
15211 * or a negative error code
15212 * Based on ALC880 version - had to change it to override
15213 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15214static int alc861vd_parse_auto_config(struct hda_codec *codec)
15215{
15216 struct alc_spec *spec = codec->spec;
15217 int err;
15218 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15219
f12ab1e0
TI
15220 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15221 alc861vd_ignore);
15222 if (err < 0)
f32610ed 15223 return err;
f12ab1e0 15224 if (!spec->autocfg.line_outs)
f32610ed
JS
15225 return 0; /* can't find valid BIOS pin config */
15226
f12ab1e0
TI
15227 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15228 if (err < 0)
15229 return err;
15230 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15231 if (err < 0)
15232 return err;
15233 err = alc861vd_auto_create_extra_out(spec,
15234 spec->autocfg.speaker_pins[0],
15235 "Speaker");
15236 if (err < 0)
15237 return err;
15238 err = alc861vd_auto_create_extra_out(spec,
15239 spec->autocfg.hp_pins[0],
15240 "Headphone");
15241 if (err < 0)
15242 return err;
15243 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15244 if (err < 0)
f32610ed
JS
15245 return err;
15246
15247 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15248
0852d7a6 15249 if (spec->autocfg.dig_outs)
f32610ed
JS
15250 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15251
603c4019 15252 if (spec->kctls.list)
d88897ea 15253 add_mixer(spec, spec->kctls.list);
f32610ed 15254
d88897ea 15255 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
15256
15257 spec->num_mux_defs = 1;
61b9b9b1 15258 spec->input_mux = &spec->private_imux[0];
f32610ed 15259
776e184e
TI
15260 err = alc_auto_add_mic_boost(codec);
15261 if (err < 0)
15262 return err;
15263
4a79ba34
TI
15264 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15265
f32610ed
JS
15266 return 1;
15267}
15268
15269/* additional initialization for auto-configuration model */
15270static void alc861vd_auto_init(struct hda_codec *codec)
15271{
f6c7e546 15272 struct alc_spec *spec = codec->spec;
f32610ed
JS
15273 alc861vd_auto_init_multi_out(codec);
15274 alc861vd_auto_init_hp_out(codec);
15275 alc861vd_auto_init_analog_input(codec);
f511b01c 15276 alc861vd_auto_init_input_src(codec);
f6c7e546 15277 if (spec->unsol_event)
7fb0d78f 15278 alc_inithook(codec);
f32610ed
JS
15279}
15280
15281static int patch_alc861vd(struct hda_codec *codec)
15282{
15283 struct alc_spec *spec;
15284 int err, board_config;
15285
15286 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15287 if (spec == NULL)
15288 return -ENOMEM;
15289
15290 codec->spec = spec;
15291
15292 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15293 alc861vd_models,
15294 alc861vd_cfg_tbl);
15295
15296 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
6c627f39
TI
15297 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15298 "trying auto-probe from BIOS...\n", codec->chip_name);
f32610ed
JS
15299 board_config = ALC861VD_AUTO;
15300 }
15301
15302 if (board_config == ALC861VD_AUTO) {
15303 /* automatic parse from the BIOS config */
15304 err = alc861vd_parse_auto_config(codec);
15305 if (err < 0) {
15306 alc_free(codec);
15307 return err;
f12ab1e0 15308 } else if (!err) {
f32610ed
JS
15309 printk(KERN_INFO
15310 "hda_codec: Cannot set up configuration "
15311 "from BIOS. Using base mode...\n");
15312 board_config = ALC861VD_3ST;
15313 }
15314 }
15315
680cd536
KK
15316 err = snd_hda_attach_beep_device(codec, 0x23);
15317 if (err < 0) {
15318 alc_free(codec);
15319 return err;
15320 }
15321
f32610ed
JS
15322 if (board_config != ALC861VD_AUTO)
15323 setup_preset(spec, &alc861vd_presets[board_config]);
15324
2f893286 15325 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 15326 /* always turn on EAPD */
d88897ea 15327 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
15328 }
15329
f32610ed
JS
15330 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15331 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15332
f32610ed
JS
15333 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15334 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15335
15336 spec->adc_nids = alc861vd_adc_nids;
15337 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 15338 spec->capsrc_nids = alc861vd_capsrc_nids;
61b9b9b1 15339 spec->capture_style = CAPT_MIX;
f32610ed 15340
f9e336f6 15341 set_capture_mixer(spec);
45bdd1c1 15342 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 15343
2134ea4f
TI
15344 spec->vmaster_nid = 0x02;
15345
f32610ed
JS
15346 codec->patch_ops = alc_patch_ops;
15347
15348 if (board_config == ALC861VD_AUTO)
15349 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
15350#ifdef CONFIG_SND_HDA_POWER_SAVE
15351 if (!spec->loopback.amplist)
15352 spec->loopback.amplist = alc861vd_loopbacks;
15353#endif
daead538 15354 codec->proc_widget_hook = print_realtek_coef;
f32610ed
JS
15355
15356 return 0;
15357}
15358
bc9f98a9
KY
15359/*
15360 * ALC662 support
15361 *
15362 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15363 * configuration. Each pin widget can choose any input DACs and a mixer.
15364 * Each ADC is connected from a mixer of all inputs. This makes possible
15365 * 6-channel independent captures.
15366 *
15367 * In addition, an independent DAC for the multi-playback (not used in this
15368 * driver yet).
15369 */
15370#define ALC662_DIGOUT_NID 0x06
15371#define ALC662_DIGIN_NID 0x0a
15372
15373static hda_nid_t alc662_dac_nids[4] = {
15374 /* front, rear, clfe, rear_surr */
15375 0x02, 0x03, 0x04
15376};
15377
622e84cd
KY
15378static hda_nid_t alc272_dac_nids[2] = {
15379 0x02, 0x03
15380};
15381
bc9f98a9
KY
15382static hda_nid_t alc662_adc_nids[1] = {
15383 /* ADC1-2 */
15384 0x09,
15385};
e1406348 15386
622e84cd
KY
15387static hda_nid_t alc272_adc_nids[1] = {
15388 /* ADC1-2 */
15389 0x08,
15390};
15391
77a261b7 15392static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
622e84cd
KY
15393static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15394
e1406348 15395
bc9f98a9
KY
15396/* input MUX */
15397/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
15398static struct hda_input_mux alc662_capture_source = {
15399 .num_items = 4,
15400 .items = {
15401 { "Mic", 0x0 },
15402 { "Front Mic", 0x1 },
15403 { "Line", 0x2 },
15404 { "CD", 0x4 },
15405 },
15406};
15407
15408static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15409 .num_items = 2,
15410 .items = {
15411 { "Mic", 0x1 },
15412 { "Line", 0x2 },
15413 },
15414};
291702f0
KY
15415
15416static struct hda_input_mux alc662_eeepc_capture_source = {
15417 .num_items = 2,
15418 .items = {
15419 { "i-Mic", 0x1 },
15420 { "e-Mic", 0x0 },
15421 },
15422};
15423
6dda9f4a
KY
15424static struct hda_input_mux alc663_capture_source = {
15425 .num_items = 3,
15426 .items = {
15427 { "Mic", 0x0 },
15428 { "Front Mic", 0x1 },
15429 { "Line", 0x2 },
15430 },
15431};
15432
15433static struct hda_input_mux alc663_m51va_capture_source = {
15434 .num_items = 2,
15435 .items = {
15436 { "Ext-Mic", 0x0 },
15437 { "D-Mic", 0x9 },
15438 },
15439};
15440
9541ba1d
CP
15441#if 1 /* set to 0 for testing other input sources below */
15442static struct hda_input_mux alc272_nc10_capture_source = {
15443 .num_items = 2,
15444 .items = {
15445 { "Autoselect Mic", 0x0 },
15446 { "Internal Mic", 0x1 },
15447 },
15448};
15449#else
15450static struct hda_input_mux alc272_nc10_capture_source = {
15451 .num_items = 16,
15452 .items = {
15453 { "Autoselect Mic", 0x0 },
15454 { "Internal Mic", 0x1 },
15455 { "In-0x02", 0x2 },
15456 { "In-0x03", 0x3 },
15457 { "In-0x04", 0x4 },
15458 { "In-0x05", 0x5 },
15459 { "In-0x06", 0x6 },
15460 { "In-0x07", 0x7 },
15461 { "In-0x08", 0x8 },
15462 { "In-0x09", 0x9 },
15463 { "In-0x0a", 0x0a },
15464 { "In-0x0b", 0x0b },
15465 { "In-0x0c", 0x0c },
15466 { "In-0x0d", 0x0d },
15467 { "In-0x0e", 0x0e },
15468 { "In-0x0f", 0x0f },
15469 },
15470};
15471#endif
15472
bc9f98a9
KY
15473/*
15474 * 2ch mode
15475 */
15476static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15477 { 2, NULL }
15478};
15479
15480/*
15481 * 2ch mode
15482 */
15483static struct hda_verb alc662_3ST_ch2_init[] = {
15484 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15485 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15486 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15487 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15488 { } /* end */
15489};
15490
15491/*
15492 * 6ch mode
15493 */
15494static struct hda_verb alc662_3ST_ch6_init[] = {
15495 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15496 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15497 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15498 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15499 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15500 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15501 { } /* end */
15502};
15503
15504static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15505 { 2, alc662_3ST_ch2_init },
15506 { 6, alc662_3ST_ch6_init },
15507};
15508
15509/*
15510 * 2ch mode
15511 */
15512static struct hda_verb alc662_sixstack_ch6_init[] = {
15513 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15514 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15515 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15516 { } /* end */
15517};
15518
15519/*
15520 * 6ch mode
15521 */
15522static struct hda_verb alc662_sixstack_ch8_init[] = {
15523 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15524 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15525 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15526 { } /* end */
15527};
15528
15529static struct hda_channel_mode alc662_5stack_modes[2] = {
15530 { 2, alc662_sixstack_ch6_init },
15531 { 6, alc662_sixstack_ch8_init },
15532};
15533
15534/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15535 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15536 */
15537
15538static struct snd_kcontrol_new alc662_base_mixer[] = {
15539 /* output mixer control */
15540 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 15541 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15542 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 15543 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15544 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15545 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15546 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15547 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15548 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15549
15550 /*Input mixer control */
15551 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15552 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15553 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15554 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15555 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15556 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
15559 { } /* end */
15560};
15561
15562static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15563 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15564 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
15565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15566 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15567 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15568 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15569 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15570 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15571 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15572 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15573 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15574 { } /* end */
15575};
15576
15577static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15578 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15579 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15580 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 15581 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15582 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15583 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15584 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15585 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15587 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15588 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15592 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15593 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15594 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15595 { } /* end */
15596};
15597
15598static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15599 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15600 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
15601 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15602 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
15603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15604 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15605 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15606 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15607 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15608 { } /* end */
15609};
15610
291702f0 15611static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
15612 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15613 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
15614
15615 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15616 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15617 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15618
15619 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15620 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15621 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15622 { } /* end */
15623};
15624
8c427226 15625static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
15626 ALC262_HIPPO_MASTER_SWITCH,
15627 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 15628 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
15629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
15631 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15632 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15633 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15636 { } /* end */
15637};
15638
f1d4e28b
KY
15639static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15640 .ops = &snd_hda_bind_vol,
15641 .values = {
15642 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15643 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15644 0
15645 },
15646};
15647
15648static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15649 .ops = &snd_hda_bind_sw,
15650 .values = {
15651 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15652 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15653 0
15654 },
15655};
15656
6dda9f4a 15657static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
15658 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15659 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15662 { } /* end */
15663};
15664
15665static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15666 .ops = &snd_hda_bind_sw,
15667 .values = {
15668 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15669 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15670 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15671 0
15672 },
15673};
15674
15675static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15676 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15677 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15680 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15681 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15682
15683 { } /* end */
15684};
15685
15686static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15687 .ops = &snd_hda_bind_sw,
15688 .values = {
15689 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15690 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15691 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15692 0
15693 },
15694};
15695
15696static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15697 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15698 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15699 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15700 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15701 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15702 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15703 { } /* end */
15704};
15705
15706static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
15707 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15708 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
15709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15712 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15713 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15714 { } /* end */
15715};
15716
15717static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15718 .ops = &snd_hda_bind_vol,
15719 .values = {
15720 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15721 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15722 0
15723 },
15724};
15725
15726static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15727 .ops = &snd_hda_bind_sw,
15728 .values = {
15729 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15730 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15731 0
15732 },
15733};
15734
15735static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15736 HDA_BIND_VOL("Master Playback Volume",
15737 &alc663_asus_two_bind_master_vol),
15738 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15739 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
15740 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
15743 { } /* end */
15744};
15745
15746static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15747 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15748 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15749 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15750 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15751 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15752 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
15753 { } /* end */
15754};
15755
15756static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15757 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15758 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15759 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15760 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15761 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15762
15763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15765 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15766 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15767 { } /* end */
15768};
15769
15770static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15771 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15772 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15773 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15774
15775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15776 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15777 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15778 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15781 { } /* end */
15782};
15783
bc9f98a9
KY
15784static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15785 {
15786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15787 .name = "Channel Mode",
15788 .info = alc_ch_mode_info,
15789 .get = alc_ch_mode_get,
15790 .put = alc_ch_mode_put,
15791 },
15792 { } /* end */
15793};
15794
15795static struct hda_verb alc662_init_verbs[] = {
15796 /* ADC: mute amp left and right */
15797 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15798 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15799 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15800
cb53c626
TI
15801 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15802 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15803 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15804 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15805 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15806
b60dd394
KY
15807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15810 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15811 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15812 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15813
15814 /* Front Pin: output 0 (0x0c) */
15815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15816 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817
15818 /* Rear Pin: output 1 (0x0d) */
15819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15821
15822 /* CLFE Pin: output 2 (0x0e) */
15823 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15824 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15825
15826 /* Mic (rear) pin: input vref at 80% */
15827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15829 /* Front Mic pin: input vref at 80% */
15830 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15832 /* Line In pin: input */
15833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15835 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15838 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15839 /* CD pin widget for input */
15840 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15841
15842 /* FIXME: use matrix-type input source selection */
15843 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15844 /* Input mixer */
15845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 15846 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
15847
15848 /* always trun on EAPD */
15849 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15850 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15851
bc9f98a9
KY
15852 { }
15853};
15854
15855static struct hda_verb alc662_sue_init_verbs[] = {
15856 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15857 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
15858 {}
15859};
15860
15861static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15862 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15863 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15864 {}
bc9f98a9
KY
15865};
15866
8c427226
KY
15867/* Set Unsolicited Event*/
15868static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15869 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15870 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15871 {}
15872};
15873
bc9f98a9
KY
15874/*
15875 * generic initialization of ADC, input mixers and output mixers
15876 */
15877static struct hda_verb alc662_auto_init_verbs[] = {
15878 /*
15879 * Unmute ADC and set the default input to mic-in
15880 */
15881 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15882 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15883
15884 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15885 * mixer widget
15886 * Note: PASD motherboards uses the Line In 2 as the input for front
15887 * panel mic (mic 2)
15888 */
15889 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15890 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
15895
15896 /*
15897 * Set up output mixers (0x0c - 0x0f)
15898 */
15899 /* set vol=0 to output mixers */
15900 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15901 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15902 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15903
15904 /* set up input amps for analog loopback */
15905 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
15906 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15907 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15912
15913
15914 /* FIXME: use matrix-type input source selection */
15915 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15916 /* Input mixer */
15917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 15918 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
15919 { }
15920};
15921
24fb9173
TI
15922/* additional verbs for ALC663 */
15923static struct hda_verb alc663_auto_init_verbs[] = {
15924 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15925 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15926 { }
15927};
15928
6dda9f4a 15929static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
15930 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15931 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
15932 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15933 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
15934 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15937 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15938 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15939 {}
15940};
15941
15942static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15943 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15944 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15945 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15947 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15948 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15949 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15950 {}
15951};
15952
15953static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15954 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15955 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15957 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15958 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15959 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15960 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15961 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15962 {}
15963};
6dda9f4a 15964
f1d4e28b
KY
15965static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15971 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15972 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15973 {}
15974};
6dda9f4a 15975
f1d4e28b
KY
15976static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15978 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15979 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15980 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15986 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15987 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15988 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15989 {}
15990};
15991
15992static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15993 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15994 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15995 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15996 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15998 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15999 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16002 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16003 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16004 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
16005 {}
16006};
16007
16008static struct hda_verb alc663_g71v_init_verbs[] = {
16009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16010 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16011 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16012
16013 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16014 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16015 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16016
16017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16018 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16019 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16020 {}
16021};
16022
16023static struct hda_verb alc663_g50v_init_verbs[] = {
16024 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16025 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16026 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16027
16028 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16029 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16030 {}
16031};
16032
f1d4e28b
KY
16033static struct hda_verb alc662_ecs_init_verbs[] = {
16034 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16036 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16037 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16038 {}
16039};
16040
622e84cd
KY
16041static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16042 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16043 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16045 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16046 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16047 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16048 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16051 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16052 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16053 {}
16054};
16055
16056static struct hda_verb alc272_dell_init_verbs[] = {
16057 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16058 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16060 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16061 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16062 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16063 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16066 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16067 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16068 {}
16069};
16070
f1d4e28b
KY
16071static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16072 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16073 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16074 { } /* end */
16075};
16076
622e84cd
KY
16077static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16078 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16079 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16080 { } /* end */
16081};
16082
bc9f98a9
KY
16083static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16084{
16085 unsigned int present;
f12ab1e0 16086 unsigned char bits;
bc9f98a9
KY
16087
16088 present = snd_hda_codec_read(codec, 0x14, 0,
16089 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
16090 bits = present ? HDA_AMP_MUTE : 0;
16091 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16092 HDA_AMP_MUTE, bits);
bc9f98a9
KY
16093}
16094
16095static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16096{
16097 unsigned int present;
f12ab1e0 16098 unsigned char bits;
bc9f98a9
KY
16099
16100 present = snd_hda_codec_read(codec, 0x1b, 0,
16101 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
16102 bits = present ? HDA_AMP_MUTE : 0;
16103 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16104 HDA_AMP_MUTE, bits);
16105 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16106 HDA_AMP_MUTE, bits);
bc9f98a9
KY
16107}
16108
16109static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16110 unsigned int res)
16111{
16112 if ((res >> 26) == ALC880_HP_EVENT)
16113 alc662_lenovo_101e_all_automute(codec);
16114 if ((res >> 26) == ALC880_FRONT_EVENT)
16115 alc662_lenovo_101e_ispeaker_automute(codec);
16116}
16117
291702f0
KY
16118static void alc662_eeepc_mic_automute(struct hda_codec *codec)
16119{
16120 unsigned int present;
16121
16122 present = snd_hda_codec_read(codec, 0x18, 0,
16123 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16124 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16125 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16126 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16127 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16128 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16129 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16130 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16131 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16132}
16133
16134/* unsolicited event for HP jack sensing */
16135static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16136 unsigned int res)
16137{
291702f0
KY
16138 if ((res >> 26) == ALC880_MIC_EVENT)
16139 alc662_eeepc_mic_automute(codec);
42171c17
TI
16140 else
16141 alc262_hippo_unsol_event(codec, res);
291702f0
KY
16142}
16143
16144static void alc662_eeepc_inithook(struct hda_codec *codec)
16145{
42171c17 16146 alc262_hippo1_init_hook(codec);
291702f0
KY
16147 alc662_eeepc_mic_automute(codec);
16148}
16149
8c427226
KY
16150static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16151{
42171c17
TI
16152 struct alc_spec *spec = codec->spec;
16153
16154 spec->autocfg.hp_pins[0] = 0x14;
16155 spec->autocfg.speaker_pins[0] = 0x1b;
16156 alc262_hippo_master_update(codec);
8c427226
KY
16157}
16158
6dda9f4a
KY
16159static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16160{
16161 unsigned int present;
16162 unsigned char bits;
16163
16164 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
16165 AC_VERB_GET_PIN_SENSE, 0)
16166 & AC_PINSENSE_PRESENCE;
6dda9f4a 16167 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
16168 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16169 AMP_IN_MUTE(0), bits);
16170 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16171 AMP_IN_MUTE(0), bits);
16172}
16173
16174static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16175{
16176 unsigned int present;
16177 unsigned char bits;
16178
16179 present = snd_hda_codec_read(codec, 0x21, 0,
16180 AC_VERB_GET_PIN_SENSE, 0)
16181 & AC_PINSENSE_PRESENCE;
16182 bits = present ? HDA_AMP_MUTE : 0;
16183 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16184 AMP_IN_MUTE(0), bits);
16185 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16186 AMP_IN_MUTE(0), bits);
16187 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16188 AMP_IN_MUTE(0), bits);
16189 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16190 AMP_IN_MUTE(0), bits);
16191}
16192
16193static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16194{
16195 unsigned int present;
16196 unsigned char bits;
16197
16198 present = snd_hda_codec_read(codec, 0x15, 0,
16199 AC_VERB_GET_PIN_SENSE, 0)
16200 & AC_PINSENSE_PRESENCE;
16201 bits = present ? HDA_AMP_MUTE : 0;
16202 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16203 AMP_IN_MUTE(0), bits);
16204 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16205 AMP_IN_MUTE(0), bits);
16206 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16207 AMP_IN_MUTE(0), bits);
16208 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16209 AMP_IN_MUTE(0), bits);
16210}
16211
16212static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16213{
16214 unsigned int present;
16215 unsigned char bits;
16216
16217 present = snd_hda_codec_read(codec, 0x1b, 0,
16218 AC_VERB_GET_PIN_SENSE, 0)
16219 & AC_PINSENSE_PRESENCE;
16220 bits = present ? 0 : PIN_OUT;
16221 snd_hda_codec_write(codec, 0x14, 0,
16222 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16223}
16224
16225static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16226{
16227 unsigned int present1, present2;
16228
16229 present1 = snd_hda_codec_read(codec, 0x21, 0,
16230 AC_VERB_GET_PIN_SENSE, 0)
16231 & AC_PINSENSE_PRESENCE;
16232 present2 = snd_hda_codec_read(codec, 0x15, 0,
16233 AC_VERB_GET_PIN_SENSE, 0)
16234 & AC_PINSENSE_PRESENCE;
16235
16236 if (present1 || present2) {
16237 snd_hda_codec_write_cache(codec, 0x14, 0,
16238 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16239 } else {
16240 snd_hda_codec_write_cache(codec, 0x14, 0,
16241 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16242 }
16243}
16244
16245static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16246{
16247 unsigned int present1, present2;
16248
16249 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16250 AC_VERB_GET_PIN_SENSE, 0)
16251 & AC_PINSENSE_PRESENCE;
16252 present2 = snd_hda_codec_read(codec, 0x15, 0,
16253 AC_VERB_GET_PIN_SENSE, 0)
16254 & AC_PINSENSE_PRESENCE;
16255
16256 if (present1 || present2) {
16257 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16258 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16260 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16261 } else {
16262 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16263 AMP_IN_MUTE(0), 0);
16264 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16265 AMP_IN_MUTE(0), 0);
16266 }
6dda9f4a
KY
16267}
16268
16269static void alc663_m51va_mic_automute(struct hda_codec *codec)
16270{
16271 unsigned int present;
16272
16273 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
16274 AC_VERB_GET_PIN_SENSE, 0)
16275 & AC_PINSENSE_PRESENCE;
6dda9f4a 16276 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16277 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 16278 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16279 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 16280 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16281 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 16282 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16283 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
16284}
16285
16286static void alc663_m51va_unsol_event(struct hda_codec *codec,
16287 unsigned int res)
16288{
16289 switch (res >> 26) {
16290 case ALC880_HP_EVENT:
16291 alc663_m51va_speaker_automute(codec);
16292 break;
16293 case ALC880_MIC_EVENT:
16294 alc663_m51va_mic_automute(codec);
16295 break;
16296 }
16297}
16298
16299static void alc663_m51va_inithook(struct hda_codec *codec)
16300{
16301 alc663_m51va_speaker_automute(codec);
16302 alc663_m51va_mic_automute(codec);
16303}
16304
f1d4e28b
KY
16305/* ***************** Mode1 ******************************/
16306static void alc663_mode1_unsol_event(struct hda_codec *codec,
16307 unsigned int res)
16308{
16309 switch (res >> 26) {
16310 case ALC880_HP_EVENT:
16311 alc663_m51va_speaker_automute(codec);
16312 break;
16313 case ALC880_MIC_EVENT:
16314 alc662_eeepc_mic_automute(codec);
16315 break;
16316 }
16317}
16318
16319static void alc663_mode1_inithook(struct hda_codec *codec)
16320{
16321 alc663_m51va_speaker_automute(codec);
16322 alc662_eeepc_mic_automute(codec);
16323}
16324/* ***************** Mode2 ******************************/
16325static void alc662_mode2_unsol_event(struct hda_codec *codec,
16326 unsigned int res)
16327{
16328 switch (res >> 26) {
16329 case ALC880_HP_EVENT:
16330 alc662_f5z_speaker_automute(codec);
16331 break;
16332 case ALC880_MIC_EVENT:
16333 alc662_eeepc_mic_automute(codec);
16334 break;
16335 }
16336}
16337
16338static void alc662_mode2_inithook(struct hda_codec *codec)
16339{
16340 alc662_f5z_speaker_automute(codec);
16341 alc662_eeepc_mic_automute(codec);
16342}
16343/* ***************** Mode3 ******************************/
16344static void alc663_mode3_unsol_event(struct hda_codec *codec,
16345 unsigned int res)
16346{
16347 switch (res >> 26) {
16348 case ALC880_HP_EVENT:
16349 alc663_two_hp_m1_speaker_automute(codec);
16350 break;
16351 case ALC880_MIC_EVENT:
16352 alc662_eeepc_mic_automute(codec);
16353 break;
16354 }
16355}
16356
16357static void alc663_mode3_inithook(struct hda_codec *codec)
16358{
16359 alc663_two_hp_m1_speaker_automute(codec);
16360 alc662_eeepc_mic_automute(codec);
16361}
16362/* ***************** Mode4 ******************************/
16363static void alc663_mode4_unsol_event(struct hda_codec *codec,
16364 unsigned int res)
16365{
16366 switch (res >> 26) {
16367 case ALC880_HP_EVENT:
16368 alc663_21jd_two_speaker_automute(codec);
16369 break;
16370 case ALC880_MIC_EVENT:
16371 alc662_eeepc_mic_automute(codec);
16372 break;
16373 }
16374}
16375
16376static void alc663_mode4_inithook(struct hda_codec *codec)
16377{
16378 alc663_21jd_two_speaker_automute(codec);
16379 alc662_eeepc_mic_automute(codec);
16380}
16381/* ***************** Mode5 ******************************/
16382static void alc663_mode5_unsol_event(struct hda_codec *codec,
16383 unsigned int res)
16384{
16385 switch (res >> 26) {
16386 case ALC880_HP_EVENT:
16387 alc663_15jd_two_speaker_automute(codec);
16388 break;
16389 case ALC880_MIC_EVENT:
16390 alc662_eeepc_mic_automute(codec);
16391 break;
16392 }
16393}
16394
16395static void alc663_mode5_inithook(struct hda_codec *codec)
16396{
16397 alc663_15jd_two_speaker_automute(codec);
16398 alc662_eeepc_mic_automute(codec);
16399}
16400/* ***************** Mode6 ******************************/
16401static void alc663_mode6_unsol_event(struct hda_codec *codec,
16402 unsigned int res)
16403{
16404 switch (res >> 26) {
16405 case ALC880_HP_EVENT:
16406 alc663_two_hp_m2_speaker_automute(codec);
16407 break;
16408 case ALC880_MIC_EVENT:
16409 alc662_eeepc_mic_automute(codec);
16410 break;
16411 }
16412}
16413
16414static void alc663_mode6_inithook(struct hda_codec *codec)
16415{
16416 alc663_two_hp_m2_speaker_automute(codec);
16417 alc662_eeepc_mic_automute(codec);
16418}
16419
6dda9f4a
KY
16420static void alc663_g71v_hp_automute(struct hda_codec *codec)
16421{
16422 unsigned int present;
16423 unsigned char bits;
16424
16425 present = snd_hda_codec_read(codec, 0x21, 0,
16426 AC_VERB_GET_PIN_SENSE, 0)
16427 & AC_PINSENSE_PRESENCE;
16428 bits = present ? HDA_AMP_MUTE : 0;
16429 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16430 HDA_AMP_MUTE, bits);
16431 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16432 HDA_AMP_MUTE, bits);
16433}
16434
16435static void alc663_g71v_front_automute(struct hda_codec *codec)
16436{
16437 unsigned int present;
16438 unsigned char bits;
16439
16440 present = snd_hda_codec_read(codec, 0x15, 0,
16441 AC_VERB_GET_PIN_SENSE, 0)
16442 & AC_PINSENSE_PRESENCE;
16443 bits = present ? HDA_AMP_MUTE : 0;
16444 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16445 HDA_AMP_MUTE, bits);
16446}
16447
16448static void alc663_g71v_unsol_event(struct hda_codec *codec,
16449 unsigned int res)
16450{
16451 switch (res >> 26) {
16452 case ALC880_HP_EVENT:
16453 alc663_g71v_hp_automute(codec);
16454 break;
16455 case ALC880_FRONT_EVENT:
16456 alc663_g71v_front_automute(codec);
16457 break;
16458 case ALC880_MIC_EVENT:
16459 alc662_eeepc_mic_automute(codec);
16460 break;
16461 }
16462}
16463
16464static void alc663_g71v_inithook(struct hda_codec *codec)
16465{
16466 alc663_g71v_front_automute(codec);
16467 alc663_g71v_hp_automute(codec);
16468 alc662_eeepc_mic_automute(codec);
16469}
16470
16471static void alc663_g50v_unsol_event(struct hda_codec *codec,
16472 unsigned int res)
16473{
16474 switch (res >> 26) {
16475 case ALC880_HP_EVENT:
16476 alc663_m51va_speaker_automute(codec);
16477 break;
16478 case ALC880_MIC_EVENT:
16479 alc662_eeepc_mic_automute(codec);
16480 break;
16481 }
16482}
16483
16484static void alc663_g50v_inithook(struct hda_codec *codec)
16485{
16486 alc663_m51va_speaker_automute(codec);
16487 alc662_eeepc_mic_automute(codec);
16488}
16489
f1d4e28b
KY
16490static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16491 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 16492 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
16493
16494 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16495 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16496 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16497
16498 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16499 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16500 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16501 { } /* end */
16502};
16503
9541ba1d
CP
16504static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16505 /* Master Playback automatically created from Speaker and Headphone */
16506 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16507 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16508 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16509 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16510
16511 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16512 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16513 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16514
16515 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16516 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16517 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16518 { } /* end */
16519};
16520
cb53c626
TI
16521#ifdef CONFIG_SND_HDA_POWER_SAVE
16522#define alc662_loopbacks alc880_loopbacks
16523#endif
16524
bc9f98a9
KY
16525
16526/* pcm configuration: identiacal with ALC880 */
16527#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16528#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16529#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16530#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16531
16532/*
16533 * configuration and preset
16534 */
16535static const char *alc662_models[ALC662_MODEL_LAST] = {
16536 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16537 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16538 [ALC662_3ST_6ch] = "3stack-6ch",
16539 [ALC662_5ST_DIG] = "6stack-dig",
16540 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 16541 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 16542 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 16543 [ALC662_ECS] = "ecs",
6dda9f4a
KY
16544 [ALC663_ASUS_M51VA] = "m51va",
16545 [ALC663_ASUS_G71V] = "g71v",
16546 [ALC663_ASUS_H13] = "h13",
16547 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
16548 [ALC663_ASUS_MODE1] = "asus-mode1",
16549 [ALC662_ASUS_MODE2] = "asus-mode2",
16550 [ALC663_ASUS_MODE3] = "asus-mode3",
16551 [ALC663_ASUS_MODE4] = "asus-mode4",
16552 [ALC663_ASUS_MODE5] = "asus-mode5",
16553 [ALC663_ASUS_MODE6] = "asus-mode6",
01f2bd48
TI
16554 [ALC272_DELL] = "dell",
16555 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 16556 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
16557 [ALC662_AUTO] = "auto",
16558};
16559
16560static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 16561 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
16562 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16563 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 16564 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509
TI
16565 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16566 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 16567 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 16568 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 16569 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16570 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16571 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16572 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16573 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16574 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16575 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd
KY
16576 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16577 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16578 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 16579 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16580 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16581 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16582 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 16583 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 16584 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16585 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16586 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16587 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 16588 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 16589 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd
KY
16590 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16591 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16592 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
16593 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16594 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16595 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 16596 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
16597 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16598 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 16599 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
16600 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16601 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16602 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16603 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16604 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 16605 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 16606 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16607 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
16608 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16609 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16610 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16611 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
16612 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16613 ALC662_3ST_6ch_DIG),
9541ba1d 16614 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
16615 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16616 ALC662_3ST_6ch_DIG),
19c009aa 16617 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 16618 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 16619 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 16620 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 16621 ALC662_3ST_6ch_DIG),
dea0a509
TI
16622 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16623 ALC663_ASUS_H13),
bc9f98a9
KY
16624 {}
16625};
16626
16627static struct alc_config_preset alc662_presets[] = {
16628 [ALC662_3ST_2ch_DIG] = {
f9e336f6 16629 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
16630 .init_verbs = { alc662_init_verbs },
16631 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16632 .dac_nids = alc662_dac_nids,
16633 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16634 .dig_in_nid = ALC662_DIGIN_NID,
16635 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16636 .channel_mode = alc662_3ST_2ch_modes,
16637 .input_mux = &alc662_capture_source,
16638 },
16639 [ALC662_3ST_6ch_DIG] = {
f9e336f6 16640 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16641 .init_verbs = { alc662_init_verbs },
16642 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16643 .dac_nids = alc662_dac_nids,
16644 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16645 .dig_in_nid = ALC662_DIGIN_NID,
16646 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16647 .channel_mode = alc662_3ST_6ch_modes,
16648 .need_dac_fix = 1,
16649 .input_mux = &alc662_capture_source,
f12ab1e0 16650 },
bc9f98a9 16651 [ALC662_3ST_6ch] = {
f9e336f6 16652 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16653 .init_verbs = { alc662_init_verbs },
16654 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16655 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16656 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16657 .channel_mode = alc662_3ST_6ch_modes,
16658 .need_dac_fix = 1,
16659 .input_mux = &alc662_capture_source,
f12ab1e0 16660 },
bc9f98a9 16661 [ALC662_5ST_DIG] = {
f9e336f6 16662 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16663 .init_verbs = { alc662_init_verbs },
16664 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16665 .dac_nids = alc662_dac_nids,
16666 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16667 .dig_in_nid = ALC662_DIGIN_NID,
16668 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16669 .channel_mode = alc662_5stack_modes,
16670 .input_mux = &alc662_capture_source,
16671 },
16672 [ALC662_LENOVO_101E] = {
f9e336f6 16673 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
16674 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16675 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16676 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16677 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16678 .channel_mode = alc662_3ST_2ch_modes,
16679 .input_mux = &alc662_lenovo_101e_capture_source,
16680 .unsol_event = alc662_lenovo_101e_unsol_event,
16681 .init_hook = alc662_lenovo_101e_all_automute,
16682 },
291702f0 16683 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 16684 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
16685 .init_verbs = { alc662_init_verbs,
16686 alc662_eeepc_sue_init_verbs },
16687 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16688 .dac_nids = alc662_dac_nids,
291702f0
KY
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 = alc662_eeepc_unsol_event,
16693 .init_hook = alc662_eeepc_inithook,
16694 },
8c427226 16695 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 16696 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
16697 alc662_chmode_mixer },
16698 .init_verbs = { alc662_init_verbs,
16699 alc662_eeepc_ep20_sue_init_verbs },
16700 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16701 .dac_nids = alc662_dac_nids,
8c427226
KY
16702 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16703 .channel_mode = alc662_3ST_6ch_modes,
16704 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 16705 .unsol_event = alc662_eeepc_unsol_event,
8c427226
KY
16706 .init_hook = alc662_eeepc_ep20_inithook,
16707 },
f1d4e28b 16708 [ALC662_ECS] = {
f9e336f6 16709 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
16710 .init_verbs = { alc662_init_verbs,
16711 alc662_ecs_init_verbs },
16712 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16713 .dac_nids = alc662_dac_nids,
16714 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16715 .channel_mode = alc662_3ST_2ch_modes,
16716 .input_mux = &alc662_eeepc_capture_source,
16717 .unsol_event = alc662_eeepc_unsol_event,
16718 .init_hook = alc662_eeepc_inithook,
16719 },
6dda9f4a 16720 [ALC663_ASUS_M51VA] = {
f9e336f6 16721 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16722 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16723 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16724 .dac_nids = alc662_dac_nids,
16725 .dig_out_nid = ALC662_DIGOUT_NID,
16726 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16727 .channel_mode = alc662_3ST_2ch_modes,
16728 .input_mux = &alc663_m51va_capture_source,
16729 .unsol_event = alc663_m51va_unsol_event,
16730 .init_hook = alc663_m51va_inithook,
16731 },
16732 [ALC663_ASUS_G71V] = {
f9e336f6 16733 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
16734 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16735 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16736 .dac_nids = alc662_dac_nids,
16737 .dig_out_nid = ALC662_DIGOUT_NID,
16738 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16739 .channel_mode = alc662_3ST_2ch_modes,
16740 .input_mux = &alc662_eeepc_capture_source,
16741 .unsol_event = alc663_g71v_unsol_event,
16742 .init_hook = alc663_g71v_inithook,
16743 },
16744 [ALC663_ASUS_H13] = {
f9e336f6 16745 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16746 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16747 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16748 .dac_nids = alc662_dac_nids,
16749 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16750 .channel_mode = alc662_3ST_2ch_modes,
16751 .input_mux = &alc663_m51va_capture_source,
16752 .unsol_event = alc663_m51va_unsol_event,
16753 .init_hook = alc663_m51va_inithook,
16754 },
16755 [ALC663_ASUS_G50V] = {
f9e336f6 16756 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
16757 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16758 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16759 .dac_nids = alc662_dac_nids,
16760 .dig_out_nid = ALC662_DIGOUT_NID,
16761 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16762 .channel_mode = alc662_3ST_6ch_modes,
16763 .input_mux = &alc663_capture_source,
16764 .unsol_event = alc663_g50v_unsol_event,
16765 .init_hook = alc663_g50v_inithook,
16766 },
f1d4e28b 16767 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
16768 .mixers = { alc663_m51va_mixer },
16769 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16770 .init_verbs = { alc662_init_verbs,
16771 alc663_21jd_amic_init_verbs },
16772 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16773 .hp_nid = 0x03,
16774 .dac_nids = alc662_dac_nids,
16775 .dig_out_nid = ALC662_DIGOUT_NID,
16776 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16777 .channel_mode = alc662_3ST_2ch_modes,
16778 .input_mux = &alc662_eeepc_capture_source,
16779 .unsol_event = alc663_mode1_unsol_event,
16780 .init_hook = alc663_mode1_inithook,
16781 },
16782 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
16783 .mixers = { alc662_1bjd_mixer },
16784 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16785 .init_verbs = { alc662_init_verbs,
16786 alc662_1bjd_amic_init_verbs },
16787 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16788 .dac_nids = alc662_dac_nids,
16789 .dig_out_nid = ALC662_DIGOUT_NID,
16790 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16791 .channel_mode = alc662_3ST_2ch_modes,
16792 .input_mux = &alc662_eeepc_capture_source,
16793 .unsol_event = alc662_mode2_unsol_event,
16794 .init_hook = alc662_mode2_inithook,
16795 },
16796 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
16797 .mixers = { alc663_two_hp_m1_mixer },
16798 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16799 .init_verbs = { alc662_init_verbs,
16800 alc663_two_hp_amic_m1_init_verbs },
16801 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16802 .hp_nid = 0x03,
16803 .dac_nids = alc662_dac_nids,
16804 .dig_out_nid = ALC662_DIGOUT_NID,
16805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16806 .channel_mode = alc662_3ST_2ch_modes,
16807 .input_mux = &alc662_eeepc_capture_source,
16808 .unsol_event = alc663_mode3_unsol_event,
16809 .init_hook = alc663_mode3_inithook,
16810 },
16811 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
16812 .mixers = { alc663_asus_21jd_clfe_mixer },
16813 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16814 .init_verbs = { alc662_init_verbs,
16815 alc663_21jd_amic_init_verbs},
16816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16817 .hp_nid = 0x03,
16818 .dac_nids = alc662_dac_nids,
16819 .dig_out_nid = ALC662_DIGOUT_NID,
16820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16821 .channel_mode = alc662_3ST_2ch_modes,
16822 .input_mux = &alc662_eeepc_capture_source,
16823 .unsol_event = alc663_mode4_unsol_event,
16824 .init_hook = alc663_mode4_inithook,
16825 },
16826 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
16827 .mixers = { alc663_asus_15jd_clfe_mixer },
16828 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16829 .init_verbs = { alc662_init_verbs,
16830 alc663_15jd_amic_init_verbs },
16831 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16832 .hp_nid = 0x03,
16833 .dac_nids = alc662_dac_nids,
16834 .dig_out_nid = ALC662_DIGOUT_NID,
16835 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16836 .channel_mode = alc662_3ST_2ch_modes,
16837 .input_mux = &alc662_eeepc_capture_source,
16838 .unsol_event = alc663_mode5_unsol_event,
16839 .init_hook = alc663_mode5_inithook,
16840 },
16841 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
16842 .mixers = { alc663_two_hp_m2_mixer },
16843 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16844 .init_verbs = { alc662_init_verbs,
16845 alc663_two_hp_amic_m2_init_verbs },
16846 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16847 .hp_nid = 0x03,
16848 .dac_nids = alc662_dac_nids,
16849 .dig_out_nid = ALC662_DIGOUT_NID,
16850 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16851 .channel_mode = alc662_3ST_2ch_modes,
16852 .input_mux = &alc662_eeepc_capture_source,
16853 .unsol_event = alc663_mode6_unsol_event,
16854 .init_hook = alc663_mode6_inithook,
16855 },
622e84cd
KY
16856 [ALC272_DELL] = {
16857 .mixers = { alc663_m51va_mixer },
16858 .cap_mixer = alc272_auto_capture_mixer,
16859 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16860 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16861 .dac_nids = alc662_dac_nids,
16862 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16863 .adc_nids = alc272_adc_nids,
16864 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16865 .capsrc_nids = alc272_capsrc_nids,
16866 .channel_mode = alc662_3ST_2ch_modes,
16867 .input_mux = &alc663_m51va_capture_source,
16868 .unsol_event = alc663_m51va_unsol_event,
16869 .init_hook = alc663_m51va_inithook,
16870 },
16871 [ALC272_DELL_ZM1] = {
16872 .mixers = { alc663_m51va_mixer },
16873 .cap_mixer = alc662_auto_capture_mixer,
16874 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16875 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16876 .dac_nids = alc662_dac_nids,
16877 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16878 .adc_nids = alc662_adc_nids,
16879 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16880 .capsrc_nids = alc662_capsrc_nids,
16881 .channel_mode = alc662_3ST_2ch_modes,
16882 .input_mux = &alc663_m51va_capture_source,
16883 .unsol_event = alc663_m51va_unsol_event,
16884 .init_hook = alc663_m51va_inithook,
16885 },
9541ba1d
CP
16886 [ALC272_SAMSUNG_NC10] = {
16887 .mixers = { alc272_nc10_mixer },
16888 .init_verbs = { alc662_init_verbs,
16889 alc663_21jd_amic_init_verbs },
16890 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16891 .dac_nids = alc272_dac_nids,
16892 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16893 .channel_mode = alc662_3ST_2ch_modes,
16894 .input_mux = &alc272_nc10_capture_source,
16895 .unsol_event = alc663_mode4_unsol_event,
16896 .init_hook = alc663_mode4_inithook,
16897 },
bc9f98a9
KY
16898};
16899
16900
16901/*
16902 * BIOS auto configuration
16903 */
16904
16905/* add playback controls from the parsed DAC table */
16906static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16907 const struct auto_pin_cfg *cfg)
16908{
16909 char name[32];
16910 static const char *chname[4] = {
16911 "Front", "Surround", NULL /*CLFE*/, "Side"
16912 };
16913 hda_nid_t nid;
16914 int i, err;
16915
16916 for (i = 0; i < cfg->line_outs; i++) {
16917 if (!spec->multiout.dac_nids[i])
16918 continue;
b60dd394 16919 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
16920 if (i == 2) {
16921 /* Center/LFE */
16922 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16923 "Center Playback Volume",
f12ab1e0
TI
16924 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16925 HDA_OUTPUT));
bc9f98a9
KY
16926 if (err < 0)
16927 return err;
16928 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16929 "LFE Playback Volume",
f12ab1e0
TI
16930 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16931 HDA_OUTPUT));
bc9f98a9
KY
16932 if (err < 0)
16933 return err;
b69ce01a 16934 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16935 "Center Playback Switch",
b69ce01a 16936 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 16937 HDA_INPUT));
bc9f98a9
KY
16938 if (err < 0)
16939 return err;
b69ce01a 16940 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16941 "LFE Playback Switch",
b69ce01a 16942 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 16943 HDA_INPUT));
bc9f98a9
KY
16944 if (err < 0)
16945 return err;
16946 } else {
16947 sprintf(name, "%s Playback Volume", chname[i]);
16948 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
16949 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16950 HDA_OUTPUT));
bc9f98a9
KY
16951 if (err < 0)
16952 return err;
16953 sprintf(name, "%s Playback Switch", chname[i]);
b69ce01a
HRK
16954 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16955 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16956 3, 0, HDA_INPUT));
bc9f98a9
KY
16957 if (err < 0)
16958 return err;
16959 }
16960 }
16961 return 0;
16962}
16963
16964/* add playback controls for speaker and HP outputs */
16965static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16966 const char *pfx)
16967{
16968 hda_nid_t nid;
16969 int err;
16970 char name[32];
16971
16972 if (!pin)
16973 return 0;
16974
24fb9173
TI
16975 if (pin == 0x17) {
16976 /* ALC663 has a mono output pin on 0x17 */
16977 sprintf(name, "%s Playback Switch", pfx);
16978 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16979 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16980 return err;
16981 }
16982
bc9f98a9
KY
16983 if (alc880_is_fixed_pin(pin)) {
16984 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
939778ae 16985 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
bc9f98a9
KY
16986 /* specify the DAC as the extra output */
16987 if (!spec->multiout.hp_nid)
16988 spec->multiout.hp_nid = nid;
16989 else
16990 spec->multiout.extra_out_nid[0] = nid;
16991 /* control HP volume/switch on the output mixer amp */
16992 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16993 sprintf(name, "%s Playback Volume", pfx);
16994 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16995 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16996 if (err < 0)
16997 return err;
16998 sprintf(name, "%s Playback Switch", pfx);
16999 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
17000 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
17001 if (err < 0)
17002 return err;
17003 } else if (alc880_is_multi_pin(pin)) {
17004 /* set manual connection */
17005 /* we have only a switch on HP-out PIN */
17006 sprintf(name, "%s Playback Switch", pfx);
17007 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17008 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17009 if (err < 0)
17010 return err;
17011 }
17012 return 0;
17013}
17014
2d864c49
TI
17015/* return the index of the src widget from the connection list of the nid.
17016 * return -1 if not found
17017 */
17018static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
17019 hda_nid_t src)
17020{
17021 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
17022 int i, conns;
17023
17024 conns = snd_hda_get_connections(codec, nid, conn_list,
17025 ARRAY_SIZE(conn_list));
17026 if (conns < 0)
17027 return -1;
17028 for (i = 0; i < conns; i++)
17029 if (conn_list[i] == src)
17030 return i;
17031 return -1;
17032}
17033
17034static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
17035{
1327a32b 17036 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2d864c49
TI
17037 return (pincap & AC_PINCAP_IN) != 0;
17038}
17039
bc9f98a9 17040/* create playback/capture controls for input pins */
2d864c49 17041static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
bc9f98a9
KY
17042 const struct auto_pin_cfg *cfg)
17043{
2d864c49 17044 struct alc_spec *spec = codec->spec;
61b9b9b1 17045 struct hda_input_mux *imux = &spec->private_imux[0];
bc9f98a9
KY
17046 int i, err, idx;
17047
17048 for (i = 0; i < AUTO_PIN_LAST; i++) {
2d864c49
TI
17049 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
17050 idx = alc662_input_pin_idx(codec, 0x0b,
17051 cfg->input_pins[i]);
17052 if (idx >= 0) {
17053 err = new_analog_input(spec, cfg->input_pins[i],
17054 auto_pin_cfg_labels[i],
17055 idx, 0x0b);
17056 if (err < 0)
17057 return err;
17058 }
17059 idx = alc662_input_pin_idx(codec, 0x22,
17060 cfg->input_pins[i]);
17061 if (idx >= 0) {
17062 imux->items[imux->num_items].label =
17063 auto_pin_cfg_labels[i];
17064 imux->items[imux->num_items].index = idx;
17065 imux->num_items++;
17066 }
bc9f98a9
KY
17067 }
17068 }
17069 return 0;
17070}
17071
17072static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17073 hda_nid_t nid, int pin_type,
17074 int dac_idx)
17075{
f6c7e546 17076 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
17077 /* need the manual connection? */
17078 if (alc880_is_multi_pin(nid)) {
17079 struct alc_spec *spec = codec->spec;
17080 int idx = alc880_multi_pin_idx(nid);
17081 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
17082 AC_VERB_SET_CONNECT_SEL,
17083 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
17084 }
17085}
17086
17087static void alc662_auto_init_multi_out(struct hda_codec *codec)
17088{
17089 struct alc_spec *spec = codec->spec;
17090 int i;
17091
17092 for (i = 0; i <= HDA_SIDE; i++) {
17093 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17094 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 17095 if (nid)
baba8ee9 17096 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
17097 i);
17098 }
17099}
17100
17101static void alc662_auto_init_hp_out(struct hda_codec *codec)
17102{
17103 struct alc_spec *spec = codec->spec;
17104 hda_nid_t pin;
17105
17106 pin = spec->autocfg.hp_pins[0];
17107 if (pin) /* connect to front */
17108 /* use dac 0 */
17109 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17110 pin = spec->autocfg.speaker_pins[0];
17111 if (pin)
17112 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
17113}
17114
bc9f98a9
KY
17115#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17116
17117static void alc662_auto_init_analog_input(struct hda_codec *codec)
17118{
17119 struct alc_spec *spec = codec->spec;
17120 int i;
17121
17122 for (i = 0; i < AUTO_PIN_LAST; i++) {
17123 hda_nid_t nid = spec->autocfg.input_pins[i];
2d864c49 17124 if (alc662_is_input_pin(codec, nid)) {
23f0c048 17125 alc_set_input_pin(codec, nid, i);
52ca15b7 17126 if (nid != ALC662_PIN_CD_NID &&
e82c025b 17127 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
17128 snd_hda_codec_write(codec, nid, 0,
17129 AC_VERB_SET_AMP_GAIN_MUTE,
17130 AMP_OUT_MUTE);
17131 }
17132 }
17133}
17134
f511b01c
TI
17135#define alc662_auto_init_input_src alc882_auto_init_input_src
17136
bc9f98a9
KY
17137static int alc662_parse_auto_config(struct hda_codec *codec)
17138{
17139 struct alc_spec *spec = codec->spec;
17140 int err;
17141 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17142
17143 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17144 alc662_ignore);
17145 if (err < 0)
17146 return err;
17147 if (!spec->autocfg.line_outs)
17148 return 0; /* can't find valid BIOS pin config */
17149
f12ab1e0
TI
17150 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17151 if (err < 0)
17152 return err;
17153 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17154 if (err < 0)
17155 return err;
17156 err = alc662_auto_create_extra_out(spec,
17157 spec->autocfg.speaker_pins[0],
17158 "Speaker");
17159 if (err < 0)
17160 return err;
17161 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17162 "Headphone");
17163 if (err < 0)
17164 return err;
2d864c49 17165 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
f12ab1e0 17166 if (err < 0)
bc9f98a9
KY
17167 return err;
17168
17169 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17170
0852d7a6 17171 if (spec->autocfg.dig_outs)
bc9f98a9
KY
17172 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17173
603c4019 17174 if (spec->kctls.list)
d88897ea 17175 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
17176
17177 spec->num_mux_defs = 1;
61b9b9b1 17178 spec->input_mux = &spec->private_imux[0];
ea1fb29a 17179
d88897ea 17180 add_verb(spec, alc662_auto_init_verbs);
24fb9173 17181 if (codec->vendor_id == 0x10ec0663)
d88897ea 17182 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
17183
17184 err = alc_auto_add_mic_boost(codec);
17185 if (err < 0)
17186 return err;
17187
4a79ba34
TI
17188 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17189
8c87286f 17190 return 1;
bc9f98a9
KY
17191}
17192
17193/* additional initialization for auto-configuration model */
17194static void alc662_auto_init(struct hda_codec *codec)
17195{
f6c7e546 17196 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
17197 alc662_auto_init_multi_out(codec);
17198 alc662_auto_init_hp_out(codec);
17199 alc662_auto_init_analog_input(codec);
f511b01c 17200 alc662_auto_init_input_src(codec);
f6c7e546 17201 if (spec->unsol_event)
7fb0d78f 17202 alc_inithook(codec);
bc9f98a9
KY
17203}
17204
17205static int patch_alc662(struct hda_codec *codec)
17206{
17207 struct alc_spec *spec;
17208 int err, board_config;
17209
17210 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17211 if (!spec)
17212 return -ENOMEM;
17213
17214 codec->spec = spec;
17215
2c3bf9ab
TI
17216 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17217
bc9f98a9
KY
17218 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17219 alc662_models,
17220 alc662_cfg_tbl);
17221 if (board_config < 0) {
6c627f39
TI
17222 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17223 "trying auto-probe from BIOS...\n", codec->chip_name);
bc9f98a9
KY
17224 board_config = ALC662_AUTO;
17225 }
17226
17227 if (board_config == ALC662_AUTO) {
17228 /* automatic parse from the BIOS config */
17229 err = alc662_parse_auto_config(codec);
17230 if (err < 0) {
17231 alc_free(codec);
17232 return err;
8c87286f 17233 } else if (!err) {
bc9f98a9
KY
17234 printk(KERN_INFO
17235 "hda_codec: Cannot set up configuration "
17236 "from BIOS. Using base mode...\n");
17237 board_config = ALC662_3ST_2ch_DIG;
17238 }
17239 }
17240
680cd536
KK
17241 err = snd_hda_attach_beep_device(codec, 0x1);
17242 if (err < 0) {
17243 alc_free(codec);
17244 return err;
17245 }
17246
bc9f98a9
KY
17247 if (board_config != ALC662_AUTO)
17248 setup_preset(spec, &alc662_presets[board_config]);
17249
bc9f98a9
KY
17250 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17251 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17252
bc9f98a9
KY
17253 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17254 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17255
e1406348
TI
17256 spec->adc_nids = alc662_adc_nids;
17257 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17258 spec->capsrc_nids = alc662_capsrc_nids;
61b9b9b1 17259 spec->capture_style = CAPT_MIX;
bc9f98a9 17260
f9e336f6
TI
17261 if (!spec->cap_mixer)
17262 set_capture_mixer(spec);
b9591448
TI
17263 if (codec->vendor_id == 0x10ec0662)
17264 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17265 else
17266 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f9e336f6 17267
2134ea4f
TI
17268 spec->vmaster_nid = 0x02;
17269
bc9f98a9
KY
17270 codec->patch_ops = alc_patch_ops;
17271 if (board_config == ALC662_AUTO)
17272 spec->init_hook = alc662_auto_init;
cb53c626
TI
17273#ifdef CONFIG_SND_HDA_POWER_SAVE
17274 if (!spec->loopback.amplist)
17275 spec->loopback.amplist = alc662_loopbacks;
17276#endif
daead538 17277 codec->proc_widget_hook = print_realtek_coef;
bc9f98a9
KY
17278
17279 return 0;
17280}
17281
1da177e4
LT
17282/*
17283 * patch entries
17284 */
1289e9e8 17285static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 17286 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 17287 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 17288 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 17289 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 17290 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 17291 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 17292 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 17293 .patch = patch_alc861 },
f32610ed
JS
17294 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17295 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17296 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
17297 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17298 .patch = patch_alc883 },
17299 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17300 .patch = patch_alc662 },
6dda9f4a 17301 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 17302 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 17303 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 17304 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
669faba2
CM
17305 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17306 .patch = patch_alc882 }, /* should be patch_alc883() in future */
cb308f97 17307 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 17308 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 17309 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
a385a529 17310 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
4442608d
KY
17311 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17312 .patch = patch_alc883 },
3fea2cb0 17313 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 17314 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
17315 {} /* terminator */
17316};
1289e9e8
TI
17317
17318MODULE_ALIAS("snd-hda-codec-id:10ec*");
17319
17320MODULE_LICENSE("GPL");
17321MODULE_DESCRIPTION("Realtek HD-audio codec");
17322
17323static struct hda_codec_preset_list realtek_list = {
17324 .preset = snd_hda_preset_realtek,
17325 .owner = THIS_MODULE,
17326};
17327
17328static int __init patch_realtek_init(void)
17329{
17330 return snd_hda_add_codec_preset(&realtek_list);
17331}
17332
17333static void __exit patch_realtek_exit(void)
17334{
17335 snd_hda_delete_codec_preset(&realtek_list);
17336}
17337
17338module_init(patch_realtek_init)
17339module_exit(patch_realtek_exit)