]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Add support of Alienware M17x laptop
[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,
9c7f852e
TI
211 ALC883_3ST_2ch_DIG,
212 ALC883_3ST_6ch_DIG,
213 ALC883_3ST_6ch,
214 ALC883_6ST_DIG,
ccc656ce
KY
215 ALC883_TARGA_DIG,
216 ALC883_TARGA_2ch_DIG,
64a8be74 217 ALC883_TARGA_8ch_DIG,
bab282b9 218 ALC883_ACER,
2880a867 219 ALC883_ACER_ASPIRE,
5b2d1eca 220 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 221 ALC888_ACER_ASPIRE_6530G,
3b315d70 222 ALC888_ACER_ASPIRE_8930G,
fc86f954 223 ALC888_ACER_ASPIRE_7730G,
c07584c8 224 ALC883_MEDION,
ea1fb29a 225 ALC883_MEDION_MD2,
b373bdeb 226 ALC883_LAPTOP_EAPD,
bc9f98a9 227 ALC883_LENOVO_101E_2ch,
272a527c 228 ALC883_LENOVO_NB0763,
189609ae 229 ALC888_LENOVO_MS7195_DIG,
e2757d5e 230 ALC888_LENOVO_SKY,
ea1fb29a 231 ALC883_HAIER_W66,
4723c022 232 ALC888_3ST_HP,
5795b9e6 233 ALC888_6ST_DELL,
a8848bd6 234 ALC883_MITAC,
0c4cc443 235 ALC883_CLEVO_M720,
fb97dc67 236 ALC883_FUJITSU_PI2515,
ef8ef5fb 237 ALC888_FUJITSU_XA3530,
17bba1b7 238 ALC883_3ST_6ch_INTEL,
87a8c370
JK
239 ALC889A_INTEL,
240 ALC889_INTEL,
e2757d5e
KY
241 ALC888_ASUS_M90V,
242 ALC888_ASUS_EEE1601,
eb4c41d3 243 ALC889A_MB31,
3ab90935 244 ALC1200_ASUS_P5Q,
3e1647c5 245 ALC883_SONY_VAIO_TT,
4953550a
TI
246 ALC882_AUTO,
247 ALC882_MODEL_LAST,
9c7f852e
TI
248};
249
df694daa
KY
250/* for GPIO Poll */
251#define GPIO_MASK 0x03
252
4a79ba34
TI
253/* extra amp-initialization sequence types */
254enum {
255 ALC_INIT_NONE,
256 ALC_INIT_DEFAULT,
257 ALC_INIT_GPIO1,
258 ALC_INIT_GPIO2,
259 ALC_INIT_GPIO3,
260};
261
6c819492
TI
262struct alc_mic_route {
263 hda_nid_t pin;
264 unsigned char mux_idx;
265 unsigned char amix_idx;
266};
267
268#define MUX_IDX_UNDEF ((unsigned char)-1)
269
1da177e4
LT
270struct alc_spec {
271 /* codec parameterization */
df694daa 272 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 273 unsigned int num_mixers;
f9e336f6 274 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 275 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 276
df694daa 277 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
278 * don't forget NULL
279 * termination!
e9edcee0
TI
280 */
281 unsigned int num_init_verbs;
1da177e4 282
aa563af7 283 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
284 struct hda_pcm_stream *stream_analog_playback;
285 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
286 struct hda_pcm_stream *stream_analog_alt_playback;
287 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 288
aa563af7 289 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
290 struct hda_pcm_stream *stream_digital_playback;
291 struct hda_pcm_stream *stream_digital_capture;
292
293 /* playback */
16ded525
TI
294 struct hda_multi_out multiout; /* playback set-up
295 * max_channels, dacs must be set
296 * dig_out_nid and hp_nid are optional
297 */
6330079f 298 hda_nid_t alt_dac_nid;
6a05ac4a 299 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 300 int dig_out_type;
1da177e4
LT
301
302 /* capture */
303 unsigned int num_adc_nids;
304 hda_nid_t *adc_nids;
e1406348 305 hda_nid_t *capsrc_nids;
16ded525 306 hda_nid_t dig_in_nid; /* digital-in NID; optional */
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];
6c819492
TI
312 struct alc_mic_route ext_mic;
313 struct alc_mic_route int_mic;
1da177e4
LT
314
315 /* channel model */
d2a6d7dc 316 const struct hda_channel_mode *channel_mode;
1da177e4 317 int num_channel_mode;
4e195a7b 318 int need_dac_fix;
3b315d70
HM
319 int const_channel_count;
320 int ext_channel_count;
1da177e4
LT
321
322 /* PCM information */
4c5186ed 323 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 324
e9edcee0
TI
325 /* dynamic controls, init_verbs and input_mux */
326 struct auto_pin_cfg autocfg;
603c4019 327 struct snd_array kctls;
61b9b9b1 328 struct hda_input_mux private_imux[3];
41923e44 329 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
330 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
331 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 332
ae6b813a
TI
333 /* hooks */
334 void (*init_hook)(struct hda_codec *codec);
335 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
336
834be88d
TI
337 /* for pin sensing */
338 unsigned int sense_updated: 1;
339 unsigned int jack_present: 1;
bec15c3a 340 unsigned int master_sw: 1;
6c819492 341 unsigned int auto_mic:1;
cb53c626 342
e64f14f4
TI
343 /* other flags */
344 unsigned int no_analog :1; /* digital I/O only */
4a79ba34 345 int init_amp;
e64f14f4 346
2134ea4f
TI
347 /* for virtual master */
348 hda_nid_t vmaster_nid;
cb53c626
TI
349#ifdef CONFIG_SND_HDA_POWER_SAVE
350 struct hda_loopback_check loopback;
351#endif
2c3bf9ab
TI
352
353 /* for PLL fix */
354 hda_nid_t pll_nid;
355 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
356};
357
358/*
359 * configuration template - to be copied to the spec instance
360 */
361struct alc_config_preset {
9c7f852e
TI
362 struct snd_kcontrol_new *mixers[5]; /* should be identical size
363 * with spec
364 */
f9e336f6 365 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
366 const struct hda_verb *init_verbs[5];
367 unsigned int num_dacs;
368 hda_nid_t *dac_nids;
369 hda_nid_t dig_out_nid; /* optional */
370 hda_nid_t hp_nid; /* optional */
b25c9da1 371 hda_nid_t *slave_dig_outs;
df694daa
KY
372 unsigned int num_adc_nids;
373 hda_nid_t *adc_nids;
e1406348 374 hda_nid_t *capsrc_nids;
df694daa
KY
375 hda_nid_t dig_in_nid;
376 unsigned int num_channel_mode;
377 const struct hda_channel_mode *channel_mode;
4e195a7b 378 int need_dac_fix;
3b315d70 379 int const_channel_count;
a1e8d2da 380 unsigned int num_mux_defs;
df694daa 381 const struct hda_input_mux *input_mux;
ae6b813a 382 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 383 void (*setup)(struct hda_codec *);
ae6b813a 384 void (*init_hook)(struct hda_codec *);
cb53c626
TI
385#ifdef CONFIG_SND_HDA_POWER_SAVE
386 struct hda_amp_list *loopbacks;
387#endif
1da177e4
LT
388};
389
1da177e4
LT
390
391/*
392 * input MUX handling
393 */
9c7f852e
TI
394static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
396{
397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
398 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
399 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
400 if (mux_idx >= spec->num_mux_defs)
401 mux_idx = 0;
402 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
403}
404
9c7f852e
TI
405static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
406 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
407{
408 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
409 struct alc_spec *spec = codec->spec;
410 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
411
412 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
413 return 0;
414}
415
9c7f852e
TI
416static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
417 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
418{
419 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
420 struct alc_spec *spec = codec->spec;
cd896c33 421 const struct hda_input_mux *imux;
1da177e4 422 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 423 unsigned int mux_idx;
e1406348
TI
424 hda_nid_t nid = spec->capsrc_nids ?
425 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 426 unsigned int type;
1da177e4 427
cd896c33
TI
428 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
429 imux = &spec->input_mux[mux_idx];
430
a22d543a 431 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 432 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
433 /* Matrix-mixer style (e.g. ALC882) */
434 unsigned int *cur_val = &spec->cur_mux[adc_idx];
435 unsigned int i, idx;
436
437 idx = ucontrol->value.enumerated.item[0];
438 if (idx >= imux->num_items)
439 idx = imux->num_items - 1;
440 if (*cur_val == idx)
441 return 0;
442 for (i = 0; i < imux->num_items; i++) {
443 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
444 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
445 imux->items[i].index,
446 HDA_AMP_MUTE, v);
447 }
448 *cur_val = idx;
449 return 1;
450 } else {
451 /* MUX style (e.g. ALC880) */
cd896c33 452 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
453 &spec->cur_mux[adc_idx]);
454 }
455}
e9edcee0 456
1da177e4
LT
457/*
458 * channel mode setting
459 */
9c7f852e
TI
460static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
461 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
462{
463 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
464 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
465 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
466 spec->num_channel_mode);
1da177e4
LT
467}
468
9c7f852e
TI
469static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
471{
472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
473 struct alc_spec *spec = codec->spec;
d2a6d7dc 474 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 475 spec->num_channel_mode,
3b315d70 476 spec->ext_channel_count);
1da177e4
LT
477}
478
9c7f852e
TI
479static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
480 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
481{
482 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
483 struct alc_spec *spec = codec->spec;
4e195a7b
TI
484 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
485 spec->num_channel_mode,
3b315d70
HM
486 &spec->ext_channel_count);
487 if (err >= 0 && !spec->const_channel_count) {
488 spec->multiout.max_channels = spec->ext_channel_count;
489 if (spec->need_dac_fix)
490 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
491 }
4e195a7b 492 return err;
1da177e4
LT
493}
494
a9430dd8 495/*
4c5186ed 496 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 497 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
498 * being part of a format specifier. Maximum allowed length of a value is
499 * 63 characters plus NULL terminator.
7cf51e48
JW
500 *
501 * Note: some retasking pin complexes seem to ignore requests for input
502 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
503 * are requested. Therefore order this list so that this behaviour will not
504 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
505 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
506 * March 2006.
4c5186ed
JW
507 */
508static char *alc_pin_mode_names[] = {
7cf51e48
JW
509 "Mic 50pc bias", "Mic 80pc bias",
510 "Line in", "Line out", "Headphone out",
4c5186ed
JW
511};
512static unsigned char alc_pin_mode_values[] = {
7cf51e48 513 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
514};
515/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
516 * in the pin being assumed to be exclusively an input or an output pin. In
517 * addition, "input" pins may or may not process the mic bias option
518 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
519 * accept requests for bias as of chip versions up to March 2006) and/or
520 * wiring in the computer.
a9430dd8 521 */
a1e8d2da
JW
522#define ALC_PIN_DIR_IN 0x00
523#define ALC_PIN_DIR_OUT 0x01
524#define ALC_PIN_DIR_INOUT 0x02
525#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
526#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 527
ea1fb29a 528/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
529 * For each direction the minimum and maximum values are given.
530 */
a1e8d2da 531static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
532 { 0, 2 }, /* ALC_PIN_DIR_IN */
533 { 3, 4 }, /* ALC_PIN_DIR_OUT */
534 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
535 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
536 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
537};
538#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
539#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
540#define alc_pin_mode_n_items(_dir) \
541 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
542
9c7f852e
TI
543static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
a9430dd8 545{
4c5186ed
JW
546 unsigned int item_num = uinfo->value.enumerated.item;
547 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
548
549 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 550 uinfo->count = 1;
4c5186ed
JW
551 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
552
553 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
554 item_num = alc_pin_mode_min(dir);
555 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
556 return 0;
557}
558
9c7f852e
TI
559static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
560 struct snd_ctl_elem_value *ucontrol)
a9430dd8 561{
4c5186ed 562 unsigned int i;
a9430dd8
JW
563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 565 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 566 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
567 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
568 AC_VERB_GET_PIN_WIDGET_CONTROL,
569 0x00);
a9430dd8 570
4c5186ed
JW
571 /* Find enumerated value for current pinctl setting */
572 i = alc_pin_mode_min(dir);
4b35d2ca 573 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 574 i++;
9c7f852e 575 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
576 return 0;
577}
578
9c7f852e
TI
579static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
580 struct snd_ctl_elem_value *ucontrol)
a9430dd8 581{
4c5186ed 582 signed int change;
a9430dd8
JW
583 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
584 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
585 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
586 long val = *ucontrol->value.integer.value;
9c7f852e
TI
587 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
588 AC_VERB_GET_PIN_WIDGET_CONTROL,
589 0x00);
a9430dd8 590
f12ab1e0 591 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
592 val = alc_pin_mode_min(dir);
593
594 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
595 if (change) {
596 /* Set pin mode to that requested */
82beb8fd
TI
597 snd_hda_codec_write_cache(codec, nid, 0,
598 AC_VERB_SET_PIN_WIDGET_CONTROL,
599 alc_pin_mode_values[val]);
cdcd9268 600
ea1fb29a 601 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
602 * for the requested pin mode. Enum values of 2 or less are
603 * input modes.
604 *
605 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
606 * reduces noise slightly (particularly on input) so we'll
607 * do it. However, having both input and output buffers
608 * enabled simultaneously doesn't seem to be problematic if
609 * this turns out to be necessary in the future.
cdcd9268
JW
610 */
611 if (val <= 2) {
47fd830a
TI
612 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
613 HDA_AMP_MUTE, HDA_AMP_MUTE);
614 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
615 HDA_AMP_MUTE, 0);
cdcd9268 616 } else {
47fd830a
TI
617 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
618 HDA_AMP_MUTE, HDA_AMP_MUTE);
619 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
620 HDA_AMP_MUTE, 0);
cdcd9268
JW
621 }
622 }
a9430dd8
JW
623 return change;
624}
625
4c5186ed 626#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 627 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
628 .info = alc_pin_mode_info, \
629 .get = alc_pin_mode_get, \
630 .put = alc_pin_mode_put, \
631 .private_value = nid | (dir<<16) }
df694daa 632
5c8f858d
JW
633/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
634 * together using a mask with more than one bit set. This control is
635 * currently used only by the ALC260 test model. At this stage they are not
636 * needed for any "production" models.
637 */
638#ifdef CONFIG_SND_DEBUG
a5ce8890 639#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 640
9c7f852e
TI
641static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
642 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
643{
644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
645 hda_nid_t nid = kcontrol->private_value & 0xffff;
646 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
647 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
648 unsigned int val = snd_hda_codec_read(codec, nid, 0,
649 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
650
651 *valp = (val & mask) != 0;
652 return 0;
653}
9c7f852e
TI
654static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
656{
657 signed int change;
658 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
659 hda_nid_t nid = kcontrol->private_value & 0xffff;
660 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
661 long val = *ucontrol->value.integer.value;
9c7f852e
TI
662 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
663 AC_VERB_GET_GPIO_DATA,
664 0x00);
5c8f858d
JW
665
666 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
667 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
668 if (val == 0)
5c8f858d
JW
669 gpio_data &= ~mask;
670 else
671 gpio_data |= mask;
82beb8fd
TI
672 snd_hda_codec_write_cache(codec, nid, 0,
673 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
674
675 return change;
676}
677#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
678 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
679 .info = alc_gpio_data_info, \
680 .get = alc_gpio_data_get, \
681 .put = alc_gpio_data_put, \
682 .private_value = nid | (mask<<16) }
683#endif /* CONFIG_SND_DEBUG */
684
92621f13
JW
685/* A switch control to allow the enabling of the digital IO pins on the
686 * ALC260. This is incredibly simplistic; the intention of this control is
687 * to provide something in the test model allowing digital outputs to be
688 * identified if present. If models are found which can utilise these
689 * outputs a more complete mixer control can be devised for those models if
690 * necessary.
691 */
692#ifdef CONFIG_SND_DEBUG
a5ce8890 693#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 694
9c7f852e
TI
695static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
697{
698 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
699 hda_nid_t nid = kcontrol->private_value & 0xffff;
700 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
701 long *valp = ucontrol->value.integer.value;
9c7f852e 702 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 703 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
704
705 *valp = (val & mask) != 0;
706 return 0;
707}
9c7f852e
TI
708static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
709 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
710{
711 signed int change;
712 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
713 hda_nid_t nid = kcontrol->private_value & 0xffff;
714 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
715 long val = *ucontrol->value.integer.value;
9c7f852e 716 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 717 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 718 0x00);
92621f13
JW
719
720 /* Set/unset the masked control bit(s) as needed */
9c7f852e 721 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
722 if (val==0)
723 ctrl_data &= ~mask;
724 else
725 ctrl_data |= mask;
82beb8fd
TI
726 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
727 ctrl_data);
92621f13
JW
728
729 return change;
730}
731#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
732 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
733 .info = alc_spdif_ctrl_info, \
734 .get = alc_spdif_ctrl_get, \
735 .put = alc_spdif_ctrl_put, \
736 .private_value = nid | (mask<<16) }
737#endif /* CONFIG_SND_DEBUG */
738
f8225f6d
JW
739/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
740 * Again, this is only used in the ALC26x test models to help identify when
741 * the EAPD line must be asserted for features to work.
742 */
743#ifdef CONFIG_SND_DEBUG
744#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
745
746static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
747 struct snd_ctl_elem_value *ucontrol)
748{
749 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
750 hda_nid_t nid = kcontrol->private_value & 0xffff;
751 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
752 long *valp = ucontrol->value.integer.value;
753 unsigned int val = snd_hda_codec_read(codec, nid, 0,
754 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
755
756 *valp = (val & mask) != 0;
757 return 0;
758}
759
760static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
762{
763 int change;
764 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
765 hda_nid_t nid = kcontrol->private_value & 0xffff;
766 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
767 long val = *ucontrol->value.integer.value;
768 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
769 AC_VERB_GET_EAPD_BTLENABLE,
770 0x00);
771
772 /* Set/unset the masked control bit(s) as needed */
773 change = (!val ? 0 : mask) != (ctrl_data & mask);
774 if (!val)
775 ctrl_data &= ~mask;
776 else
777 ctrl_data |= mask;
778 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
779 ctrl_data);
780
781 return change;
782}
783
784#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
785 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
786 .info = alc_eapd_ctrl_info, \
787 .get = alc_eapd_ctrl_get, \
788 .put = alc_eapd_ctrl_put, \
789 .private_value = nid | (mask<<16) }
790#endif /* CONFIG_SND_DEBUG */
791
23f0c048
TI
792/*
793 * set up the input pin config (depending on the given auto-pin type)
794 */
795static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
796 int auto_pin_type)
797{
798 unsigned int val = PIN_IN;
799
800 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
801 unsigned int pincap;
1327a32b 802 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
803 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
804 if (pincap & AC_PINCAP_VREF_80)
805 val = PIN_VREF80;
461c6c3a
TI
806 else if (pincap & AC_PINCAP_VREF_50)
807 val = PIN_VREF50;
808 else if (pincap & AC_PINCAP_VREF_100)
809 val = PIN_VREF100;
810 else if (pincap & AC_PINCAP_VREF_GRD)
811 val = PIN_VREFGRD;
23f0c048
TI
812 }
813 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
814}
815
d88897ea
TI
816/*
817 */
818static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
819{
820 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
821 return;
822 spec->mixers[spec->num_mixers++] = mix;
823}
824
825static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
826{
827 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
828 return;
829 spec->init_verbs[spec->num_init_verbs++] = verb;
830}
831
daead538
TI
832#ifdef CONFIG_PROC_FS
833/*
834 * hook for proc
835 */
836static void print_realtek_coef(struct snd_info_buffer *buffer,
837 struct hda_codec *codec, hda_nid_t nid)
838{
839 int coeff;
840
841 if (nid != 0x20)
842 return;
843 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
844 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
845 coeff = snd_hda_codec_read(codec, nid, 0,
846 AC_VERB_GET_COEF_INDEX, 0);
847 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
848}
849#else
850#define print_realtek_coef NULL
851#endif
852
df694daa
KY
853/*
854 * set up from the preset table
855 */
e9c364c0 856static void setup_preset(struct hda_codec *codec,
9c7f852e 857 const struct alc_config_preset *preset)
df694daa 858{
e9c364c0 859 struct alc_spec *spec = codec->spec;
df694daa
KY
860 int i;
861
862 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 863 add_mixer(spec, preset->mixers[i]);
f9e336f6 864 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
865 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
866 i++)
d88897ea 867 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 868
df694daa
KY
869 spec->channel_mode = preset->channel_mode;
870 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 871 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 872 spec->const_channel_count = preset->const_channel_count;
df694daa 873
3b315d70
HM
874 if (preset->const_channel_count)
875 spec->multiout.max_channels = preset->const_channel_count;
876 else
877 spec->multiout.max_channels = spec->channel_mode[0].channels;
878 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
879
880 spec->multiout.num_dacs = preset->num_dacs;
881 spec->multiout.dac_nids = preset->dac_nids;
882 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 883 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 884 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 885
a1e8d2da 886 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 887 if (!spec->num_mux_defs)
a1e8d2da 888 spec->num_mux_defs = 1;
df694daa
KY
889 spec->input_mux = preset->input_mux;
890
891 spec->num_adc_nids = preset->num_adc_nids;
892 spec->adc_nids = preset->adc_nids;
e1406348 893 spec->capsrc_nids = preset->capsrc_nids;
df694daa 894 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
895
896 spec->unsol_event = preset->unsol_event;
897 spec->init_hook = preset->init_hook;
cb53c626
TI
898#ifdef CONFIG_SND_HDA_POWER_SAVE
899 spec->loopback.amplist = preset->loopbacks;
900#endif
e9c364c0
TI
901
902 if (preset->setup)
903 preset->setup(codec);
df694daa
KY
904}
905
bc9f98a9
KY
906/* Enable GPIO mask and set output */
907static struct hda_verb alc_gpio1_init_verbs[] = {
908 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
909 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
910 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
911 { }
912};
913
914static struct hda_verb alc_gpio2_init_verbs[] = {
915 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
916 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
917 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
918 { }
919};
920
bdd148a3
KY
921static struct hda_verb alc_gpio3_init_verbs[] = {
922 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
923 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
924 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
925 { }
926};
927
2c3bf9ab
TI
928/*
929 * Fix hardware PLL issue
930 * On some codecs, the analog PLL gating control must be off while
931 * the default value is 1.
932 */
933static void alc_fix_pll(struct hda_codec *codec)
934{
935 struct alc_spec *spec = codec->spec;
936 unsigned int val;
937
938 if (!spec->pll_nid)
939 return;
940 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
941 spec->pll_coef_idx);
942 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
943 AC_VERB_GET_PROC_COEF, 0);
944 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
945 spec->pll_coef_idx);
946 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
947 val & ~(1 << spec->pll_coef_bit));
948}
949
950static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
951 unsigned int coef_idx, unsigned int coef_bit)
952{
953 struct alc_spec *spec = codec->spec;
954 spec->pll_nid = nid;
955 spec->pll_coef_idx = coef_idx;
956 spec->pll_coef_bit = coef_bit;
957 alc_fix_pll(codec);
958}
959
a9fd4f3f 960static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
961{
962 struct alc_spec *spec = codec->spec;
261c2407 963 unsigned int present, pincap;
a9fd4f3f
TI
964 unsigned int nid = spec->autocfg.hp_pins[0];
965 int i;
c9b58006 966
261c2407
TI
967 pincap = snd_hda_query_pin_caps(codec, nid);
968 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
969 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
a9fd4f3f 970 present = snd_hda_codec_read(codec, nid, 0,
c9b58006 971 AC_VERB_GET_PIN_SENSE, 0);
a9fd4f3f
TI
972 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
973 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
974 nid = spec->autocfg.speaker_pins[i];
975 if (!nid)
976 break;
977 snd_hda_codec_write(codec, nid, 0,
978 AC_VERB_SET_PIN_WIDGET_CONTROL,
979 spec->jack_present ? 0 : PIN_OUT);
980 }
c9b58006
KY
981}
982
6c819492
TI
983static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
984 hda_nid_t nid)
985{
986 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
987 int i, nums;
988
989 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
990 for (i = 0; i < nums; i++)
991 if (conn[i] == nid)
992 return i;
993 return -1;
994}
995
7fb0d78f
KY
996static void alc_mic_automute(struct hda_codec *codec)
997{
998 struct alc_spec *spec = codec->spec;
6c819492
TI
999 struct alc_mic_route *dead, *alive;
1000 unsigned int present, type;
1001 hda_nid_t cap_nid;
1002
b59bdf3b
TI
1003 if (!spec->auto_mic)
1004 return;
6c819492
TI
1005 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1006 return;
1007 if (snd_BUG_ON(!spec->adc_nids))
1008 return;
1009
1010 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1011
1012 present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0,
1013 AC_VERB_GET_PIN_SENSE, 0);
1014 present &= AC_PINSENSE_PRESENCE;
1015 if (present) {
1016 alive = &spec->ext_mic;
1017 dead = &spec->int_mic;
1018 } else {
1019 alive = &spec->int_mic;
1020 dead = &spec->ext_mic;
1021 }
1022
6c819492
TI
1023 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1024 if (type == AC_WID_AUD_MIX) {
1025 /* Matrix-mixer style (e.g. ALC882) */
1026 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1027 alive->mux_idx,
1028 HDA_AMP_MUTE, 0);
1029 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1030 dead->mux_idx,
1031 HDA_AMP_MUTE, HDA_AMP_MUTE);
1032 } else {
1033 /* MUX style (e.g. ALC880) */
1034 snd_hda_codec_write_cache(codec, cap_nid, 0,
1035 AC_VERB_SET_CONNECT_SEL,
1036 alive->mux_idx);
1037 }
1038
1039 /* FIXME: analog mixer */
7fb0d78f
KY
1040}
1041
c9b58006
KY
1042/* unsolicited event for HP jack sensing */
1043static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1044{
1045 if (codec->vendor_id == 0x10ec0880)
1046 res >>= 28;
1047 else
1048 res >>= 26;
a9fd4f3f
TI
1049 switch (res) {
1050 case ALC880_HP_EVENT:
1051 alc_automute_pin(codec);
1052 break;
1053 case ALC880_MIC_EVENT:
7fb0d78f 1054 alc_mic_automute(codec);
a9fd4f3f
TI
1055 break;
1056 }
7fb0d78f
KY
1057}
1058
1059static void alc_inithook(struct hda_codec *codec)
1060{
a9fd4f3f 1061 alc_automute_pin(codec);
7fb0d78f 1062 alc_mic_automute(codec);
c9b58006
KY
1063}
1064
f9423e7a
KY
1065/* additional initialization for ALC888 variants */
1066static void alc888_coef_init(struct hda_codec *codec)
1067{
1068 unsigned int tmp;
1069
1070 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1071 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1072 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1073 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1074 /* alc888S-VC */
1075 snd_hda_codec_read(codec, 0x20, 0,
1076 AC_VERB_SET_PROC_COEF, 0x830);
1077 else
1078 /* alc888-VB */
1079 snd_hda_codec_read(codec, 0x20, 0,
1080 AC_VERB_SET_PROC_COEF, 0x3030);
1081}
1082
87a8c370
JK
1083static void alc889_coef_init(struct hda_codec *codec)
1084{
1085 unsigned int tmp;
1086
1087 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1088 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1089 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1090 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1091}
1092
4a79ba34 1093static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1094{
4a79ba34 1095 unsigned int tmp;
bc9f98a9 1096
4a79ba34
TI
1097 switch (type) {
1098 case ALC_INIT_GPIO1:
bc9f98a9
KY
1099 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1100 break;
4a79ba34 1101 case ALC_INIT_GPIO2:
bc9f98a9
KY
1102 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1103 break;
4a79ba34 1104 case ALC_INIT_GPIO3:
bdd148a3
KY
1105 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1106 break;
4a79ba34 1107 case ALC_INIT_DEFAULT:
bdd148a3 1108 switch (codec->vendor_id) {
c9b58006
KY
1109 case 0x10ec0260:
1110 snd_hda_codec_write(codec, 0x0f, 0,
1111 AC_VERB_SET_EAPD_BTLENABLE, 2);
1112 snd_hda_codec_write(codec, 0x10, 0,
1113 AC_VERB_SET_EAPD_BTLENABLE, 2);
1114 break;
1115 case 0x10ec0262:
bdd148a3
KY
1116 case 0x10ec0267:
1117 case 0x10ec0268:
c9b58006 1118 case 0x10ec0269:
c6e8f2da 1119 case 0x10ec0272:
f9423e7a
KY
1120 case 0x10ec0660:
1121 case 0x10ec0662:
1122 case 0x10ec0663:
c9b58006 1123 case 0x10ec0862:
20a3a05d 1124 case 0x10ec0889:
bdd148a3
KY
1125 snd_hda_codec_write(codec, 0x14, 0,
1126 AC_VERB_SET_EAPD_BTLENABLE, 2);
1127 snd_hda_codec_write(codec, 0x15, 0,
1128 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 1129 break;
bdd148a3 1130 }
c9b58006
KY
1131 switch (codec->vendor_id) {
1132 case 0x10ec0260:
1133 snd_hda_codec_write(codec, 0x1a, 0,
1134 AC_VERB_SET_COEF_INDEX, 7);
1135 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1136 AC_VERB_GET_PROC_COEF, 0);
1137 snd_hda_codec_write(codec, 0x1a, 0,
1138 AC_VERB_SET_COEF_INDEX, 7);
1139 snd_hda_codec_write(codec, 0x1a, 0,
1140 AC_VERB_SET_PROC_COEF,
1141 tmp | 0x2010);
1142 break;
1143 case 0x10ec0262:
1144 case 0x10ec0880:
1145 case 0x10ec0882:
1146 case 0x10ec0883:
1147 case 0x10ec0885:
4a5a4c56 1148 case 0x10ec0887:
20a3a05d 1149 case 0x10ec0889:
87a8c370 1150 alc889_coef_init(codec);
c9b58006 1151 break;
f9423e7a 1152 case 0x10ec0888:
4a79ba34 1153 alc888_coef_init(codec);
f9423e7a 1154 break;
c9b58006
KY
1155 case 0x10ec0267:
1156 case 0x10ec0268:
1157 snd_hda_codec_write(codec, 0x20, 0,
1158 AC_VERB_SET_COEF_INDEX, 7);
1159 tmp = snd_hda_codec_read(codec, 0x20, 0,
1160 AC_VERB_GET_PROC_COEF, 0);
1161 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1162 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1163 snd_hda_codec_write(codec, 0x20, 0,
1164 AC_VERB_SET_PROC_COEF,
1165 tmp | 0x3000);
1166 break;
bc9f98a9 1167 }
4a79ba34
TI
1168 break;
1169 }
1170}
1171
1172static void alc_init_auto_hp(struct hda_codec *codec)
1173{
1174 struct alc_spec *spec = codec->spec;
1175
1176 if (!spec->autocfg.hp_pins[0])
1177 return;
1178
1179 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1180 if (spec->autocfg.line_out_pins[0] &&
1181 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1182 spec->autocfg.speaker_pins[0] =
1183 spec->autocfg.line_out_pins[0];
1184 else
1185 return;
1186 }
1187
2a2ed0df
TI
1188 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1189 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1190 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1191 AC_VERB_SET_UNSOLICITED_ENABLE,
1192 AC_USRSP_EN | ALC880_HP_EVENT);
1193 spec->unsol_event = alc_sku_unsol_event;
1194}
1195
6c819492
TI
1196static void alc_init_auto_mic(struct hda_codec *codec)
1197{
1198 struct alc_spec *spec = codec->spec;
1199 struct auto_pin_cfg *cfg = &spec->autocfg;
1200 hda_nid_t fixed, ext;
1201 int i;
1202
1203 /* there must be only two mic inputs exclusively */
1204 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1205 if (cfg->input_pins[i])
1206 return;
1207
1208 fixed = ext = 0;
1209 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1210 hda_nid_t nid = cfg->input_pins[i];
1211 unsigned int defcfg;
1212 if (!nid)
1213 return;
1214 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1215 switch (get_defcfg_connect(defcfg)) {
1216 case AC_JACK_PORT_FIXED:
1217 if (fixed)
1218 return; /* already occupied */
1219 fixed = nid;
1220 break;
1221 case AC_JACK_PORT_COMPLEX:
1222 if (ext)
1223 return; /* already occupied */
1224 ext = nid;
1225 break;
1226 default:
1227 return; /* invalid entry */
1228 }
1229 }
1230 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1231 return; /* no unsol support */
1232 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1233 ext, fixed);
1234 spec->ext_mic.pin = ext;
1235 spec->int_mic.pin = fixed;
1236 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1237 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1238 spec->auto_mic = 1;
1239 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1240 AC_VERB_SET_UNSOLICITED_ENABLE,
1241 AC_USRSP_EN | ALC880_MIC_EVENT);
1242 spec->unsol_event = alc_sku_unsol_event;
1243}
1244
4a79ba34
TI
1245/* check subsystem ID and set up device-specific initialization;
1246 * return 1 if initialized, 0 if invalid SSID
1247 */
1248/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1249 * 31 ~ 16 : Manufacture ID
1250 * 15 ~ 8 : SKU ID
1251 * 7 ~ 0 : Assembly ID
1252 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1253 */
1254static int alc_subsystem_id(struct hda_codec *codec,
1255 hda_nid_t porta, hda_nid_t porte,
1256 hda_nid_t portd)
1257{
1258 unsigned int ass, tmp, i;
1259 unsigned nid;
1260 struct alc_spec *spec = codec->spec;
1261
1262 ass = codec->subsystem_id & 0xffff;
1263 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1264 goto do_sku;
1265
1266 /* invalid SSID, check the special NID pin defcfg instead */
1267 /*
def319f9 1268 * 31~30 : port connectivity
4a79ba34
TI
1269 * 29~21 : reserve
1270 * 20 : PCBEEP input
1271 * 19~16 : Check sum (15:1)
1272 * 15~1 : Custom
1273 * 0 : override
1274 */
1275 nid = 0x1d;
1276 if (codec->vendor_id == 0x10ec0260)
1277 nid = 0x17;
1278 ass = snd_hda_codec_get_pincfg(codec, nid);
1279 snd_printd("realtek: No valid SSID, "
1280 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1281 ass, nid);
4a79ba34
TI
1282 if (!(ass & 1) && !(ass & 0x100000))
1283 return 0;
1284 if ((ass >> 30) != 1) /* no physical connection */
1285 return 0;
1286
1287 /* check sum */
1288 tmp = 0;
1289 for (i = 1; i < 16; i++) {
1290 if ((ass >> i) & 1)
1291 tmp++;
1292 }
1293 if (((ass >> 16) & 0xf) != tmp)
1294 return 0;
1295do_sku:
1296 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1297 ass & 0xffff, codec->vendor_id);
1298 /*
1299 * 0 : override
1300 * 1 : Swap Jack
1301 * 2 : 0 --> Desktop, 1 --> Laptop
1302 * 3~5 : External Amplifier control
1303 * 7~6 : Reserved
1304 */
1305 tmp = (ass & 0x38) >> 3; /* external Amp control */
1306 switch (tmp) {
1307 case 1:
1308 spec->init_amp = ALC_INIT_GPIO1;
1309 break;
1310 case 3:
1311 spec->init_amp = ALC_INIT_GPIO2;
1312 break;
1313 case 7:
1314 spec->init_amp = ALC_INIT_GPIO3;
1315 break;
1316 case 5:
1317 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1318 break;
1319 }
ea1fb29a 1320
8c427226 1321 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1322 * when the external headphone out jack is plugged"
1323 */
8c427226 1324 if (!(ass & 0x8000))
4a79ba34 1325 return 1;
c9b58006
KY
1326 /*
1327 * 10~8 : Jack location
1328 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1329 * 14~13: Resvered
1330 * 15 : 1 --> enable the function "Mute internal speaker
1331 * when the external headphone out jack is plugged"
1332 */
c9b58006
KY
1333 if (!spec->autocfg.hp_pins[0]) {
1334 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1335 if (tmp == 0)
1336 spec->autocfg.hp_pins[0] = porta;
1337 else if (tmp == 1)
1338 spec->autocfg.hp_pins[0] = porte;
1339 else if (tmp == 2)
1340 spec->autocfg.hp_pins[0] = portd;
1341 else
4a79ba34 1342 return 1;
c9b58006
KY
1343 }
1344
4a79ba34 1345 alc_init_auto_hp(codec);
6c819492 1346 alc_init_auto_mic(codec);
4a79ba34
TI
1347 return 1;
1348}
ea1fb29a 1349
4a79ba34
TI
1350static void alc_ssid_check(struct hda_codec *codec,
1351 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1352{
1353 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1354 struct alc_spec *spec = codec->spec;
1355 snd_printd("realtek: "
1356 "Enable default setup for auto mode as fallback\n");
1357 spec->init_amp = ALC_INIT_DEFAULT;
1358 alc_init_auto_hp(codec);
6c819492 1359 alc_init_auto_mic(codec);
4a79ba34 1360 }
bc9f98a9
KY
1361}
1362
f95474ec
TI
1363/*
1364 * Fix-up pin default configurations
1365 */
1366
1367struct alc_pincfg {
1368 hda_nid_t nid;
1369 u32 val;
1370};
1371
1372static void alc_fix_pincfg(struct hda_codec *codec,
1373 const struct snd_pci_quirk *quirk,
1374 const struct alc_pincfg **pinfix)
1375{
1376 const struct alc_pincfg *cfg;
1377
1378 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1379 if (!quirk)
1380 return;
1381
1382 cfg = pinfix[quirk->value];
0e8a21b5
TI
1383 for (; cfg->nid; cfg++)
1384 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
f95474ec
TI
1385}
1386
ef8ef5fb
VP
1387/*
1388 * ALC888
1389 */
1390
1391/*
1392 * 2ch mode
1393 */
1394static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1395/* Mic-in jack as mic in */
1396 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1397 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1398/* Line-in jack as Line in */
1399 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1400 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1401/* Line-Out as Front */
1402 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1403 { } /* end */
1404};
1405
1406/*
1407 * 4ch mode
1408 */
1409static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1410/* Mic-in jack as mic in */
1411 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1412 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1413/* Line-in jack as Surround */
1414 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1415 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1416/* Line-Out as Front */
1417 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1418 { } /* end */
1419};
1420
1421/*
1422 * 6ch mode
1423 */
1424static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1425/* Mic-in jack as CLFE */
1426 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1427 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1428/* Line-in jack as Surround */
1429 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1430 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1431/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1432 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1433 { } /* end */
1434};
1435
1436/*
1437 * 8ch mode
1438 */
1439static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1440/* Mic-in jack as CLFE */
1441 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1442 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1443/* Line-in jack as Surround */
1444 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1445 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1446/* Line-Out as Side */
1447 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1448 { } /* end */
1449};
1450
1451static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1452 { 2, alc888_4ST_ch2_intel_init },
1453 { 4, alc888_4ST_ch4_intel_init },
1454 { 6, alc888_4ST_ch6_intel_init },
1455 { 8, alc888_4ST_ch8_intel_init },
1456};
1457
1458/*
1459 * ALC888 Fujitsu Siemens Amillo xa3530
1460 */
1461
1462static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1463/* Front Mic: set to PIN_IN (empty by default) */
1464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1465/* Connect Internal HP to Front */
1466 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1467 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1468 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1469/* Connect Bass HP to Front */
1470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1473/* Connect Line-Out side jack (SPDIF) to Side */
1474 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1475 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1476 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1477/* Connect Mic jack to CLFE */
1478 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1479 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1481/* Connect Line-in jack to Surround */
1482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1483 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1484 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1485/* Connect HP out jack to Front */
1486 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1488 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1489/* Enable unsolicited event for HP jack and Line-out jack */
1490 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1491 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1492 {}
1493};
1494
a9fd4f3f 1495static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1496{
a9fd4f3f 1497 struct alc_spec *spec = codec->spec;
261c2407 1498 unsigned int val, mute, pincap;
a9fd4f3f
TI
1499 hda_nid_t nid;
1500 int i;
1501
1502 spec->jack_present = 0;
1503 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1504 nid = spec->autocfg.hp_pins[i];
1505 if (!nid)
1506 break;
261c2407
TI
1507 pincap = snd_hda_query_pin_caps(codec, nid);
1508 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1509 snd_hda_codec_read(codec, nid, 0,
1510 AC_VERB_SET_PIN_SENSE, 0);
a9fd4f3f
TI
1511 val = snd_hda_codec_read(codec, nid, 0,
1512 AC_VERB_GET_PIN_SENSE, 0);
1513 if (val & AC_PINSENSE_PRESENCE) {
1514 spec->jack_present = 1;
1515 break;
1516 }
1517 }
1518
1519 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1520 /* Toggle internal speakers muting */
a9fd4f3f
TI
1521 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1522 nid = spec->autocfg.speaker_pins[i];
1523 if (!nid)
1524 break;
1525 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1526 HDA_AMP_MUTE, mute);
1527 }
ef8ef5fb
VP
1528}
1529
a9fd4f3f
TI
1530static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1531 unsigned int res)
ef8ef5fb 1532{
a9fd4f3f
TI
1533 if (codec->vendor_id == 0x10ec0880)
1534 res >>= 28;
1535 else
1536 res >>= 26;
1537 if (res == ALC880_HP_EVENT)
1538 alc_automute_amp(codec);
ef8ef5fb
VP
1539}
1540
4f5d1706 1541static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1542{
1543 struct alc_spec *spec = codec->spec;
1544
1545 spec->autocfg.hp_pins[0] = 0x15;
1546 spec->autocfg.speaker_pins[0] = 0x14;
1547 spec->autocfg.speaker_pins[1] = 0x16;
1548 spec->autocfg.speaker_pins[2] = 0x17;
1549 spec->autocfg.speaker_pins[3] = 0x19;
1550 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1551}
1552
1553static void alc889_intel_init_hook(struct hda_codec *codec)
1554{
1555 alc889_coef_init(codec);
4f5d1706 1556 alc_automute_amp(codec);
6732bd0d
WF
1557}
1558
4f5d1706 1559static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1560{
1561 struct alc_spec *spec = codec->spec;
1562
1563 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1564 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1565 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1566 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1567}
ef8ef5fb 1568
5b2d1eca
VP
1569/*
1570 * ALC888 Acer Aspire 4930G model
1571 */
1572
1573static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1574/* Front Mic: set to PIN_IN (empty by default) */
1575 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1576/* Unselect Front Mic by default in input mixer 3 */
1577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1578/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1579 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1580/* Connect Internal HP to front */
1581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1584/* Connect HP out to front */
1585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1587 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1588 { }
1589};
1590
d2fd4b09
TV
1591/*
1592 * ALC888 Acer Aspire 6530G model
1593 */
1594
1595static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1596/* Bias voltage on for external mic port */
1597 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1598/* Front Mic: set to PIN_IN (empty by default) */
1599 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1600/* Unselect Front Mic by default in input mixer 3 */
1601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1602/* Enable unsolicited event for HP jack */
1603 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1604/* Enable speaker output */
1605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1607/* Enable headphone output */
1608 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1610 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1611 { }
1612};
1613
3b315d70 1614/*
018df418 1615 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1616 */
1617
018df418 1618static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1619/* Front Mic: set to PIN_IN (empty by default) */
1620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1621/* Unselect Front Mic by default in input mixer 3 */
1622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1623/* Enable unsolicited event for HP jack */
1624 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1625/* Connect Internal Front to Front */
1626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1627 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1629/* Connect Internal Rear to Rear */
1630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1631 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1633/* Connect Internal CLFE to CLFE */
1634 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1636 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1637/* Connect HP out to Front */
018df418 1638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1640 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1641/* Enable all DACs */
1642/* DAC DISABLE/MUTE 1? */
1643/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1644 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1645 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1646/* DAC DISABLE/MUTE 2? */
1647/* some bit here disables the other DACs. Init=0x4900 */
1648 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1649 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1650/* Enable amplifiers */
1651 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1652 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
018df418
HM
1653/* DMIC fix
1654 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1655 * which makes the stereo useless. However, either the mic or the ALC889
1656 * makes the signal become a difference/sum signal instead of standard
1657 * stereo, which is annoying. So instead we flip this bit which makes the
1658 * codec replicate the sum signal to both channels, turning it into a
1659 * normal mono mic.
1660 */
1661/* DMIC_CONTROL? Init value = 0x0001 */
1662 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1663 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1664 { }
1665};
1666
ef8ef5fb 1667static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1668 /* Front mic only available on one ADC */
1669 {
1670 .num_items = 4,
1671 .items = {
1672 { "Mic", 0x0 },
1673 { "Line", 0x2 },
1674 { "CD", 0x4 },
1675 { "Front Mic", 0xb },
1676 },
1677 },
1678 {
1679 .num_items = 3,
1680 .items = {
1681 { "Mic", 0x0 },
1682 { "Line", 0x2 },
1683 { "CD", 0x4 },
1684 },
1685 }
1686};
1687
d2fd4b09
TV
1688static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1689 /* Interal mic only available on one ADC */
1690 {
684a8842 1691 .num_items = 5,
d2fd4b09
TV
1692 .items = {
1693 { "Ext Mic", 0x0 },
684a8842 1694 { "Line In", 0x2 },
d2fd4b09 1695 { "CD", 0x4 },
684a8842 1696 { "Input Mix", 0xa },
d2fd4b09
TV
1697 { "Int Mic", 0xb },
1698 },
1699 },
1700 {
684a8842 1701 .num_items = 4,
d2fd4b09
TV
1702 .items = {
1703 { "Ext Mic", 0x0 },
684a8842 1704 { "Line In", 0x2 },
d2fd4b09 1705 { "CD", 0x4 },
684a8842 1706 { "Input Mix", 0xa },
d2fd4b09
TV
1707 },
1708 }
1709};
1710
018df418
HM
1711static struct hda_input_mux alc889_capture_sources[3] = {
1712 /* Digital mic only available on first "ADC" */
1713 {
1714 .num_items = 5,
1715 .items = {
1716 { "Mic", 0x0 },
1717 { "Line", 0x2 },
1718 { "CD", 0x4 },
1719 { "Front Mic", 0xb },
1720 { "Input Mix", 0xa },
1721 },
1722 },
1723 {
1724 .num_items = 4,
1725 .items = {
1726 { "Mic", 0x0 },
1727 { "Line", 0x2 },
1728 { "CD", 0x4 },
1729 { "Input Mix", 0xa },
1730 },
1731 },
1732 {
1733 .num_items = 4,
1734 .items = {
1735 { "Mic", 0x0 },
1736 { "Line", 0x2 },
1737 { "CD", 0x4 },
1738 { "Input Mix", 0xa },
1739 },
1740 }
1741};
1742
ef8ef5fb 1743static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1744 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1745 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1746 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1747 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1748 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1749 HDA_OUTPUT),
1750 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1751 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1752 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1753 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1754 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1755 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1756 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1757 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1758 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1760 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1762 { } /* end */
1763};
1764
4f5d1706 1765static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 1766{
a9fd4f3f 1767 struct alc_spec *spec = codec->spec;
5b2d1eca 1768
a9fd4f3f
TI
1769 spec->autocfg.hp_pins[0] = 0x15;
1770 spec->autocfg.speaker_pins[0] = 0x14;
5b2d1eca
VP
1771}
1772
4f5d1706 1773static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
1774{
1775 struct alc_spec *spec = codec->spec;
1776
1777 spec->autocfg.hp_pins[0] = 0x15;
1778 spec->autocfg.speaker_pins[0] = 0x14;
1779 spec->autocfg.speaker_pins[1] = 0x16;
1780 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
1781}
1782
4f5d1706 1783static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
1784{
1785 struct alc_spec *spec = codec->spec;
1786
1787 spec->autocfg.hp_pins[0] = 0x15;
1788 spec->autocfg.speaker_pins[0] = 0x14;
1789 spec->autocfg.speaker_pins[1] = 0x16;
1790 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
1791}
1792
1da177e4 1793/*
e9edcee0
TI
1794 * ALC880 3-stack model
1795 *
1796 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1797 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1798 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1799 */
1800
e9edcee0
TI
1801static hda_nid_t alc880_dac_nids[4] = {
1802 /* front, rear, clfe, rear_surr */
1803 0x02, 0x05, 0x04, 0x03
1804};
1805
1806static hda_nid_t alc880_adc_nids[3] = {
1807 /* ADC0-2 */
1808 0x07, 0x08, 0x09,
1809};
1810
1811/* The datasheet says the node 0x07 is connected from inputs,
1812 * but it shows zero connection in the real implementation on some devices.
df694daa 1813 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1814 */
e9edcee0
TI
1815static hda_nid_t alc880_adc_nids_alt[2] = {
1816 /* ADC1-2 */
1817 0x08, 0x09,
1818};
1819
1820#define ALC880_DIGOUT_NID 0x06
1821#define ALC880_DIGIN_NID 0x0a
1822
1823static struct hda_input_mux alc880_capture_source = {
1824 .num_items = 4,
1825 .items = {
1826 { "Mic", 0x0 },
1827 { "Front Mic", 0x3 },
1828 { "Line", 0x2 },
1829 { "CD", 0x4 },
1830 },
1831};
1832
1833/* channel source setting (2/6 channel selection for 3-stack) */
1834/* 2ch mode */
1835static struct hda_verb alc880_threestack_ch2_init[] = {
1836 /* set line-in to input, mute it */
1837 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1838 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1839 /* set mic-in to input vref 80%, mute it */
1840 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1841 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1842 { } /* end */
1843};
1844
1845/* 6ch mode */
1846static struct hda_verb alc880_threestack_ch6_init[] = {
1847 /* set line-in to output, unmute it */
1848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1850 /* set mic-in to output, unmute it */
1851 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1852 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1853 { } /* end */
1854};
1855
d2a6d7dc 1856static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1857 { 2, alc880_threestack_ch2_init },
1858 { 6, alc880_threestack_ch6_init },
1859};
1860
c8b6bf9b 1861static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1863 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1864 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1865 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1866 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1867 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1868 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1869 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1878 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1879 {
1880 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1881 .name = "Channel Mode",
df694daa
KY
1882 .info = alc_ch_mode_info,
1883 .get = alc_ch_mode_get,
1884 .put = alc_ch_mode_put,
e9edcee0
TI
1885 },
1886 { } /* end */
1887};
1888
1889/* capture mixer elements */
f9e336f6
TI
1890static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1891 struct snd_ctl_elem_info *uinfo)
1892{
1893 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1894 struct alc_spec *spec = codec->spec;
1895 int err;
1da177e4 1896
5a9e02e9 1897 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1898 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1899 HDA_INPUT);
1900 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1901 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1902 return err;
1903}
1904
1905static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1906 unsigned int size, unsigned int __user *tlv)
1907{
1908 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1909 struct alc_spec *spec = codec->spec;
1910 int err;
1da177e4 1911
5a9e02e9 1912 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1913 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1914 HDA_INPUT);
1915 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1916 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1917 return err;
1918}
1919
1920typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1921 struct snd_ctl_elem_value *ucontrol);
1922
1923static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1924 struct snd_ctl_elem_value *ucontrol,
1925 getput_call_t func)
1926{
1927 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1928 struct alc_spec *spec = codec->spec;
1929 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1930 int err;
1931
5a9e02e9 1932 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1933 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1934 3, 0, HDA_INPUT);
1935 err = func(kcontrol, ucontrol);
5a9e02e9 1936 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1937 return err;
1938}
1939
1940static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1941 struct snd_ctl_elem_value *ucontrol)
1942{
1943 return alc_cap_getput_caller(kcontrol, ucontrol,
1944 snd_hda_mixer_amp_volume_get);
1945}
1946
1947static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1948 struct snd_ctl_elem_value *ucontrol)
1949{
1950 return alc_cap_getput_caller(kcontrol, ucontrol,
1951 snd_hda_mixer_amp_volume_put);
1952}
1953
1954/* capture mixer elements */
1955#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1956
1957static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1958 struct snd_ctl_elem_value *ucontrol)
1959{
1960 return alc_cap_getput_caller(kcontrol, ucontrol,
1961 snd_hda_mixer_amp_switch_get);
1962}
1963
1964static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1965 struct snd_ctl_elem_value *ucontrol)
1966{
1967 return alc_cap_getput_caller(kcontrol, ucontrol,
1968 snd_hda_mixer_amp_switch_put);
1969}
1970
a23b688f 1971#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
1972 { \
1973 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1974 .name = "Capture Switch", \
1975 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1976 .count = num, \
1977 .info = alc_cap_sw_info, \
1978 .get = alc_cap_sw_get, \
1979 .put = alc_cap_sw_put, \
1980 }, \
1981 { \
1982 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1983 .name = "Capture Volume", \
1984 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1985 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1986 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1987 .count = num, \
1988 .info = alc_cap_vol_info, \
1989 .get = alc_cap_vol_get, \
1990 .put = alc_cap_vol_put, \
1991 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
1992 }
1993
1994#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
1995 { \
1996 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1997 /* .name = "Capture Source", */ \
1998 .name = "Input Source", \
1999 .count = num, \
2000 .info = alc_mux_enum_info, \
2001 .get = alc_mux_enum_get, \
2002 .put = alc_mux_enum_put, \
a23b688f
TI
2003 }
2004
2005#define DEFINE_CAPMIX(num) \
2006static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2007 _DEFINE_CAPMIX(num), \
2008 _DEFINE_CAPSRC(num), \
2009 { } /* end */ \
2010}
2011
2012#define DEFINE_CAPMIX_NOSRC(num) \
2013static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2014 _DEFINE_CAPMIX(num), \
2015 { } /* end */ \
f9e336f6
TI
2016}
2017
2018/* up to three ADCs */
2019DEFINE_CAPMIX(1);
2020DEFINE_CAPMIX(2);
2021DEFINE_CAPMIX(3);
a23b688f
TI
2022DEFINE_CAPMIX_NOSRC(1);
2023DEFINE_CAPMIX_NOSRC(2);
2024DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2025
2026/*
2027 * ALC880 5-stack model
2028 *
9c7f852e
TI
2029 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2030 * Side = 0x02 (0xd)
e9edcee0
TI
2031 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2032 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2033 */
2034
2035/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2036static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2037 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2038 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2039 { } /* end */
2040};
2041
e9edcee0
TI
2042/* channel source setting (6/8 channel selection for 5-stack) */
2043/* 6ch mode */
2044static struct hda_verb alc880_fivestack_ch6_init[] = {
2045 /* set line-in to input, mute it */
2046 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2047 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2048 { } /* end */
2049};
2050
e9edcee0
TI
2051/* 8ch mode */
2052static struct hda_verb alc880_fivestack_ch8_init[] = {
2053 /* set line-in to output, unmute it */
2054 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2055 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2056 { } /* end */
2057};
2058
d2a6d7dc 2059static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2060 { 6, alc880_fivestack_ch6_init },
2061 { 8, alc880_fivestack_ch8_init },
2062};
2063
2064
2065/*
2066 * ALC880 6-stack model
2067 *
9c7f852e
TI
2068 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2069 * Side = 0x05 (0x0f)
e9edcee0
TI
2070 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2071 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2072 */
2073
2074static hda_nid_t alc880_6st_dac_nids[4] = {
2075 /* front, rear, clfe, rear_surr */
2076 0x02, 0x03, 0x04, 0x05
f12ab1e0 2077};
e9edcee0
TI
2078
2079static struct hda_input_mux alc880_6stack_capture_source = {
2080 .num_items = 4,
2081 .items = {
2082 { "Mic", 0x0 },
2083 { "Front Mic", 0x1 },
2084 { "Line", 0x2 },
2085 { "CD", 0x4 },
2086 },
2087};
2088
2089/* fixed 8-channels */
d2a6d7dc 2090static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2091 { 8, NULL },
2092};
2093
c8b6bf9b 2094static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2096 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2097 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2098 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2099 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2100 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2101 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2102 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2103 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2104 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2105 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2106 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2107 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2108 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2112 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2113 {
2114 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2115 .name = "Channel Mode",
df694daa
KY
2116 .info = alc_ch_mode_info,
2117 .get = alc_ch_mode_get,
2118 .put = alc_ch_mode_put,
16ded525
TI
2119 },
2120 { } /* end */
2121};
2122
e9edcee0
TI
2123
2124/*
2125 * ALC880 W810 model
2126 *
2127 * W810 has rear IO for:
2128 * Front (DAC 02)
2129 * Surround (DAC 03)
2130 * Center/LFE (DAC 04)
2131 * Digital out (06)
2132 *
2133 * The system also has a pair of internal speakers, and a headphone jack.
2134 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2135 *
e9edcee0
TI
2136 * There is a variable resistor to control the speaker or headphone
2137 * volume. This is a hardware-only device without a software API.
2138 *
2139 * Plugging headphones in will disable the internal speakers. This is
2140 * implemented in hardware, not via the driver using jack sense. In
2141 * a similar fashion, plugging into the rear socket marked "front" will
2142 * disable both the speakers and headphones.
2143 *
2144 * For input, there's a microphone jack, and an "audio in" jack.
2145 * These may not do anything useful with this driver yet, because I
2146 * haven't setup any initialization verbs for these yet...
2147 */
2148
2149static hda_nid_t alc880_w810_dac_nids[3] = {
2150 /* front, rear/surround, clfe */
2151 0x02, 0x03, 0x04
16ded525
TI
2152};
2153
e9edcee0 2154/* fixed 6 channels */
d2a6d7dc 2155static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2156 { 6, NULL }
2157};
2158
2159/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2160static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2161 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2162 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2163 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2164 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2165 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2166 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2167 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2168 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2170 { } /* end */
2171};
2172
2173
2174/*
2175 * Z710V model
2176 *
2177 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2178 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2179 * Line = 0x1a
e9edcee0
TI
2180 */
2181
2182static hda_nid_t alc880_z71v_dac_nids[1] = {
2183 0x02
2184};
2185#define ALC880_Z71V_HP_DAC 0x03
2186
2187/* fixed 2 channels */
d2a6d7dc 2188static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2189 { 2, NULL }
2190};
2191
c8b6bf9b 2192static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2193 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2194 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2195 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2196 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2201 { } /* end */
2202};
2203
e9edcee0 2204
e9edcee0
TI
2205/*
2206 * ALC880 F1734 model
2207 *
2208 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2209 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2210 */
2211
2212static hda_nid_t alc880_f1734_dac_nids[1] = {
2213 0x03
2214};
2215#define ALC880_F1734_HP_DAC 0x02
2216
c8b6bf9b 2217static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2218 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2219 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2220 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2222 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2223 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2226 { } /* end */
2227};
2228
937b4160
TI
2229static struct hda_input_mux alc880_f1734_capture_source = {
2230 .num_items = 2,
2231 .items = {
2232 { "Mic", 0x1 },
2233 { "CD", 0x4 },
2234 },
2235};
2236
e9edcee0 2237
e9edcee0
TI
2238/*
2239 * ALC880 ASUS model
2240 *
2241 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2242 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2243 * Mic = 0x18, Line = 0x1a
2244 */
2245
2246#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2247#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2248
c8b6bf9b 2249static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2250 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2251 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2252 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2253 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2254 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2255 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2256 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2257 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2258 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2259 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2260 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2261 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2262 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2263 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2264 {
2265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2266 .name = "Channel Mode",
df694daa
KY
2267 .info = alc_ch_mode_info,
2268 .get = alc_ch_mode_get,
2269 .put = alc_ch_mode_put,
16ded525
TI
2270 },
2271 { } /* end */
2272};
e9edcee0 2273
e9edcee0
TI
2274/*
2275 * ALC880 ASUS W1V model
2276 *
2277 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2278 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2279 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2280 */
2281
2282/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2283static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2284 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2285 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2286 { } /* end */
2287};
2288
df694daa
KY
2289/* TCL S700 */
2290static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2292 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2294 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2295 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2298 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2299 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2300 { } /* end */
2301};
2302
ccc656ce
KY
2303/* Uniwill */
2304static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2305 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2306 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2307 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2308 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2309 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2310 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2311 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2312 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2313 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2314 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2315 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2316 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2318 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2319 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2320 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2321 {
2322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2323 .name = "Channel Mode",
2324 .info = alc_ch_mode_info,
2325 .get = alc_ch_mode_get,
2326 .put = alc_ch_mode_put,
2327 },
2328 { } /* end */
2329};
2330
2cf9f0fc
TD
2331static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2332 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2333 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2334 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2335 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2336 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2337 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2338 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2339 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2340 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2341 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2342 { } /* end */
2343};
2344
ccc656ce 2345static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2346 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2347 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2349 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2352 { } /* end */
2353};
2354
2134ea4f
TI
2355/*
2356 * virtual master controls
2357 */
2358
2359/*
2360 * slave controls for virtual master
2361 */
2362static const char *alc_slave_vols[] = {
2363 "Front Playback Volume",
2364 "Surround Playback Volume",
2365 "Center Playback Volume",
2366 "LFE Playback Volume",
2367 "Side Playback Volume",
2368 "Headphone Playback Volume",
2369 "Speaker Playback Volume",
2370 "Mono Playback Volume",
2134ea4f 2371 "Line-Out Playback Volume",
26f5df26 2372 "PCM Playback Volume",
2134ea4f
TI
2373 NULL,
2374};
2375
2376static const char *alc_slave_sws[] = {
2377 "Front Playback Switch",
2378 "Surround Playback Switch",
2379 "Center Playback Switch",
2380 "LFE Playback Switch",
2381 "Side Playback Switch",
2382 "Headphone Playback Switch",
2383 "Speaker Playback Switch",
2384 "Mono Playback Switch",
edb54a55 2385 "IEC958 Playback Switch",
2134ea4f
TI
2386 NULL,
2387};
2388
1da177e4 2389/*
e9edcee0 2390 * build control elements
1da177e4 2391 */
603c4019
TI
2392
2393static void alc_free_kctls(struct hda_codec *codec);
2394
45bdd1c1
TI
2395/* additional beep mixers; the actual parameters are overwritten at build */
2396static struct snd_kcontrol_new alc_beep_mixer[] = {
2397 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2398 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2399 { } /* end */
2400};
2401
1da177e4
LT
2402static int alc_build_controls(struct hda_codec *codec)
2403{
2404 struct alc_spec *spec = codec->spec;
2405 int err;
2406 int i;
2407
2408 for (i = 0; i < spec->num_mixers; i++) {
2409 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2410 if (err < 0)
2411 return err;
2412 }
f9e336f6
TI
2413 if (spec->cap_mixer) {
2414 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2415 if (err < 0)
2416 return err;
2417 }
1da177e4 2418 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2419 err = snd_hda_create_spdif_out_ctls(codec,
2420 spec->multiout.dig_out_nid);
1da177e4
LT
2421 if (err < 0)
2422 return err;
e64f14f4
TI
2423 if (!spec->no_analog) {
2424 err = snd_hda_create_spdif_share_sw(codec,
2425 &spec->multiout);
2426 if (err < 0)
2427 return err;
2428 spec->multiout.share_spdif = 1;
2429 }
1da177e4
LT
2430 }
2431 if (spec->dig_in_nid) {
2432 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2433 if (err < 0)
2434 return err;
2435 }
2134ea4f 2436
45bdd1c1
TI
2437 /* create beep controls if needed */
2438 if (spec->beep_amp) {
2439 struct snd_kcontrol_new *knew;
2440 for (knew = alc_beep_mixer; knew->name; knew++) {
2441 struct snd_kcontrol *kctl;
2442 kctl = snd_ctl_new1(knew, codec);
2443 if (!kctl)
2444 return -ENOMEM;
2445 kctl->private_value = spec->beep_amp;
2446 err = snd_hda_ctl_add(codec, kctl);
2447 if (err < 0)
2448 return err;
2449 }
2450 }
2451
2134ea4f 2452 /* if we have no master control, let's create it */
e64f14f4
TI
2453 if (!spec->no_analog &&
2454 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2455 unsigned int vmaster_tlv[4];
2134ea4f 2456 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2457 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2458 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2459 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2460 if (err < 0)
2461 return err;
2462 }
e64f14f4
TI
2463 if (!spec->no_analog &&
2464 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2465 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2466 NULL, alc_slave_sws);
2467 if (err < 0)
2468 return err;
2469 }
2470
603c4019 2471 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
2472 return 0;
2473}
2474
e9edcee0 2475
1da177e4
LT
2476/*
2477 * initialize the codec volumes, etc
2478 */
2479
e9edcee0
TI
2480/*
2481 * generic initialization of ADC, input mixers and output mixers
2482 */
2483static struct hda_verb alc880_volume_init_verbs[] = {
2484 /*
2485 * Unmute ADC0-2 and set the default input to mic-in
2486 */
71fe7b82 2487 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2491 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2493
e9edcee0
TI
2494 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2495 * mixer widget
9c7f852e
TI
2496 * Note: PASD motherboards uses the Line In 2 as the input for front
2497 * panel mic (mic 2)
1da177e4 2498 */
e9edcee0 2499 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2506 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2507
e9edcee0
TI
2508 /*
2509 * Set up output mixers (0x0c - 0x0f)
1da177e4 2510 */
e9edcee0
TI
2511 /* set vol=0 to output mixers */
2512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2516 /* set up input amps for analog loopback */
2517 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2520 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2524 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2525 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2526
2527 { }
2528};
2529
e9edcee0
TI
2530/*
2531 * 3-stack pin configuration:
2532 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2533 */
2534static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2535 /*
2536 * preset connection lists of input pins
2537 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2538 */
2539 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2540 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2541 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2542
2543 /*
2544 * Set pin mode and muting
2545 */
2546 /* set front pin widgets 0x14 for output */
05acb863 2547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2549 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2550 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2552 /* Mic2 (as headphone out) for HP output */
2553 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2554 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2555 /* Line In pin widget for input */
05acb863 2556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2558 /* Line2 (as front mic) pin widget for input and vref at 80% */
2559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2560 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2561 /* CD pin widget for input */
05acb863 2562 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2563
e9edcee0
TI
2564 { }
2565};
1da177e4 2566
e9edcee0
TI
2567/*
2568 * 5-stack pin configuration:
2569 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2570 * line-in/side = 0x1a, f-mic = 0x1b
2571 */
2572static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2573 /*
2574 * preset connection lists of input pins
2575 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2576 */
e9edcee0
TI
2577 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2578 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2579
e9edcee0
TI
2580 /*
2581 * Set pin mode and muting
1da177e4 2582 */
e9edcee0
TI
2583 /* set pin widgets 0x14-0x17 for output */
2584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2586 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2587 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2588 /* unmute pins for output (no gain on this amp) */
2589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2591 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2592 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2593
2594 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2595 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2597 /* Mic2 (as headphone out) for HP output */
2598 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2599 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2600 /* Line In pin widget for input */
2601 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2602 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2603 /* Line2 (as front mic) pin widget for input and vref at 80% */
2604 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2605 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2606 /* CD pin widget for input */
2607 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2608
2609 { }
2610};
2611
e9edcee0
TI
2612/*
2613 * W810 pin configuration:
2614 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2615 */
2616static struct hda_verb alc880_pin_w810_init_verbs[] = {
2617 /* hphone/speaker input selector: front DAC */
2618 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2619
05acb863 2620 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2621 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2622 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2624 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2626
e9edcee0 2627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2628 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2629
1da177e4
LT
2630 { }
2631};
2632
e9edcee0
TI
2633/*
2634 * Z71V pin configuration:
2635 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2636 */
2637static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2642
16ded525 2643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2644 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2646 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2647
2648 { }
2649};
2650
e9edcee0
TI
2651/*
2652 * 6-stack pin configuration:
9c7f852e
TI
2653 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2654 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2655 */
2656static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2657 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2658
16ded525 2659 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2660 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2661 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2663 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2665 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2666 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667
16ded525 2668 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2670 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2671 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2672 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2673 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2676 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2677
e9edcee0
TI
2678 { }
2679};
2680
ccc656ce
KY
2681/*
2682 * Uniwill pin configuration:
2683 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2684 * line = 0x1a
2685 */
2686static struct hda_verb alc880_uniwill_init_verbs[] = {
2687 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2688
2689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2693 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2694 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2695 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2696 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2699 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2701 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2703
2704 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2705 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2706 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2707 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2708 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2709 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2710 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2711 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2712 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2713
2714 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2715 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2716
2717 { }
2718};
2719
2720/*
2721* Uniwill P53
ea1fb29a 2722* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2723 */
2724static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2725 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2726
2727 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2729 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2731 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2732 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2733 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2735 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2737 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2739
2740 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2742 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2744 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2745 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2746
2747 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2748 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2749
2750 { }
2751};
2752
2cf9f0fc
TD
2753static struct hda_verb alc880_beep_init_verbs[] = {
2754 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2755 { }
2756};
2757
458a4fab
TI
2758/* auto-toggle front mic */
2759static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2760{
2761 unsigned int present;
2762 unsigned char bits;
ccc656ce
KY
2763
2764 present = snd_hda_codec_read(codec, 0x18, 0,
2765 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2766 bits = present ? HDA_AMP_MUTE : 0;
2767 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2768}
2769
4f5d1706 2770static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 2771{
a9fd4f3f
TI
2772 struct alc_spec *spec = codec->spec;
2773
2774 spec->autocfg.hp_pins[0] = 0x14;
2775 spec->autocfg.speaker_pins[0] = 0x15;
2776 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
2777}
2778
2779static void alc880_uniwill_init_hook(struct hda_codec *codec)
2780{
a9fd4f3f 2781 alc_automute_amp(codec);
458a4fab 2782 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2783}
2784
2785static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2786 unsigned int res)
2787{
2788 /* Looks like the unsol event is incompatible with the standard
2789 * definition. 4bit tag is placed at 28 bit!
2790 */
458a4fab 2791 switch (res >> 28) {
458a4fab
TI
2792 case ALC880_MIC_EVENT:
2793 alc880_uniwill_mic_automute(codec);
2794 break;
a9fd4f3f
TI
2795 default:
2796 alc_automute_amp_unsol_event(codec, res);
2797 break;
458a4fab 2798 }
ccc656ce
KY
2799}
2800
4f5d1706 2801static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 2802{
a9fd4f3f 2803 struct alc_spec *spec = codec->spec;
ccc656ce 2804
a9fd4f3f
TI
2805 spec->autocfg.hp_pins[0] = 0x14;
2806 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
2807}
2808
2809static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2810{
2811 unsigned int present;
ea1fb29a 2812
ccc656ce 2813 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2814 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2815 present &= HDA_AMP_VOLMASK;
2816 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2817 HDA_AMP_VOLMASK, present);
2818 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2819 HDA_AMP_VOLMASK, present);
ccc656ce 2820}
47fd830a 2821
ccc656ce
KY
2822static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2823 unsigned int res)
2824{
2825 /* Looks like the unsol event is incompatible with the standard
2826 * definition. 4bit tag is placed at 28 bit!
2827 */
f12ab1e0 2828 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 2829 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
2830 else
2831 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
2832}
2833
e9edcee0
TI
2834/*
2835 * F1734 pin configuration:
2836 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2837 */
2838static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2839 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2840 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2841 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2842 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2843 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2844
e9edcee0 2845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2849
e9edcee0
TI
2850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2852 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2853 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2856 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2857 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2858 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2859
937b4160
TI
2860 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2861 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2862
dfc0ff62
TI
2863 { }
2864};
2865
e9edcee0
TI
2866/*
2867 * ASUS pin configuration:
2868 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2869 */
2870static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2871 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2872 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2873 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2874 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2875
2876 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2877 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2878 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2879 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2880 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2881 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2882 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2883 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2884
2885 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2886 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2887 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2889 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2890 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2891 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2893 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2894
e9edcee0
TI
2895 { }
2896};
16ded525 2897
e9edcee0 2898/* Enable GPIO mask and set output */
bc9f98a9
KY
2899#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2900#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 2901#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
2902
2903/* Clevo m520g init */
2904static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2905 /* headphone output */
2906 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2907 /* line-out */
2908 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2910 /* Line-in */
2911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2912 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2913 /* CD */
2914 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2915 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2916 /* Mic1 (rear panel) */
2917 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2918 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 /* Mic2 (front panel) */
2920 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2921 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2922 /* headphone */
2923 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2924 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2925 /* change to EAPD mode */
2926 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2927 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2928
2929 { }
16ded525
TI
2930};
2931
df694daa 2932static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2933 /* change to EAPD mode */
2934 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2935 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2936
df694daa
KY
2937 /* Headphone output */
2938 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2939 /* Front output*/
2940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2941 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2942
2943 /* Line In pin widget for input */
2944 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2945 /* CD pin widget for input */
2946 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2947 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2948 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2949
2950 /* change to EAPD mode */
2951 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2952 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2953
2954 { }
2955};
16ded525 2956
e9edcee0 2957/*
ae6b813a
TI
2958 * LG m1 express dual
2959 *
2960 * Pin assignment:
2961 * Rear Line-In/Out (blue): 0x14
2962 * Build-in Mic-In: 0x15
2963 * Speaker-out: 0x17
2964 * HP-Out (green): 0x1b
2965 * Mic-In/Out (red): 0x19
2966 * SPDIF-Out: 0x1e
2967 */
2968
2969/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2970static hda_nid_t alc880_lg_dac_nids[3] = {
2971 0x05, 0x02, 0x03
2972};
2973
2974/* seems analog CD is not working */
2975static struct hda_input_mux alc880_lg_capture_source = {
2976 .num_items = 3,
2977 .items = {
2978 { "Mic", 0x1 },
2979 { "Line", 0x5 },
2980 { "Internal Mic", 0x6 },
2981 },
2982};
2983
2984/* 2,4,6 channel modes */
2985static struct hda_verb alc880_lg_ch2_init[] = {
2986 /* set line-in and mic-in to input */
2987 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2988 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2989 { }
2990};
2991
2992static struct hda_verb alc880_lg_ch4_init[] = {
2993 /* set line-in to out and mic-in to input */
2994 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2995 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2996 { }
2997};
2998
2999static struct hda_verb alc880_lg_ch6_init[] = {
3000 /* set line-in and mic-in to output */
3001 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3002 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3003 { }
3004};
3005
3006static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3007 { 2, alc880_lg_ch2_init },
3008 { 4, alc880_lg_ch4_init },
3009 { 6, alc880_lg_ch6_init },
3010};
3011
3012static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3013 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3014 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3015 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3016 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3017 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3018 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3019 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3020 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3025 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3026 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3027 {
3028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3029 .name = "Channel Mode",
3030 .info = alc_ch_mode_info,
3031 .get = alc_ch_mode_get,
3032 .put = alc_ch_mode_put,
3033 },
3034 { } /* end */
3035};
3036
3037static struct hda_verb alc880_lg_init_verbs[] = {
3038 /* set capture source to mic-in */
3039 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3041 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3042 /* mute all amp mixer inputs */
3043 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3044 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3045 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3046 /* line-in to input */
3047 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3048 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3049 /* built-in mic */
3050 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3051 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3052 /* speaker-out */
3053 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3054 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3055 /* mic-in to input */
3056 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3057 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3058 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3059 /* HP-out */
3060 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3061 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3063 /* jack sense */
a9fd4f3f 3064 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3065 { }
3066};
3067
3068/* toggle speaker-output according to the hp-jack state */
4f5d1706 3069static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3070{
a9fd4f3f 3071 struct alc_spec *spec = codec->spec;
ae6b813a 3072
a9fd4f3f
TI
3073 spec->autocfg.hp_pins[0] = 0x1b;
3074 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3075}
3076
d681518a
TI
3077/*
3078 * LG LW20
3079 *
3080 * Pin assignment:
3081 * Speaker-out: 0x14
3082 * Mic-In: 0x18
e4f41da9
CM
3083 * Built-in Mic-In: 0x19
3084 * Line-In: 0x1b
3085 * HP-Out: 0x1a
d681518a
TI
3086 * SPDIF-Out: 0x1e
3087 */
3088
d681518a 3089static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3090 .num_items = 3,
d681518a
TI
3091 .items = {
3092 { "Mic", 0x0 },
3093 { "Internal Mic", 0x1 },
e4f41da9 3094 { "Line In", 0x2 },
d681518a
TI
3095 },
3096};
3097
0a8c5da3
CM
3098#define alc880_lg_lw_modes alc880_threestack_modes
3099
d681518a 3100static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3102 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3103 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3104 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3105 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3107 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3108 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3113 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3114 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3115 {
3116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3117 .name = "Channel Mode",
3118 .info = alc_ch_mode_info,
3119 .get = alc_ch_mode_get,
3120 .put = alc_ch_mode_put,
3121 },
d681518a
TI
3122 { } /* end */
3123};
3124
3125static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3126 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3127 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3128 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3129
d681518a
TI
3130 /* set capture source to mic-in */
3131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3132 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3133 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3135 /* speaker-out */
3136 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3137 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3138 /* HP-out */
d681518a
TI
3139 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3141 /* mic-in to input */
3142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3143 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3144 /* built-in mic */
3145 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3146 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3147 /* jack sense */
a9fd4f3f 3148 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3149 { }
3150};
3151
3152/* toggle speaker-output according to the hp-jack state */
4f5d1706 3153static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3154{
a9fd4f3f 3155 struct alc_spec *spec = codec->spec;
d681518a 3156
a9fd4f3f
TI
3157 spec->autocfg.hp_pins[0] = 0x1b;
3158 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3159}
3160
df99cd33
TI
3161static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3162 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3163 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3166 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3167 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3168 { } /* end */
3169};
3170
3171static struct hda_input_mux alc880_medion_rim_capture_source = {
3172 .num_items = 2,
3173 .items = {
3174 { "Mic", 0x0 },
3175 { "Internal Mic", 0x1 },
3176 },
3177};
3178
3179static struct hda_verb alc880_medion_rim_init_verbs[] = {
3180 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3181
3182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3183 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3184
3185 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3187 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3188 /* Mic2 (as headphone out) for HP output */
3189 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3190 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3191 /* Internal Speaker */
3192 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3193 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3194
3195 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3196 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3197
3198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3199 { }
3200};
3201
3202/* toggle speaker-output according to the hp-jack state */
3203static void alc880_medion_rim_automute(struct hda_codec *codec)
3204{
a9fd4f3f
TI
3205 struct alc_spec *spec = codec->spec;
3206 alc_automute_amp(codec);
3207 /* toggle EAPD */
3208 if (spec->jack_present)
df99cd33
TI
3209 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3210 else
3211 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3212}
3213
3214static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3215 unsigned int res)
3216{
3217 /* Looks like the unsol event is incompatible with the standard
3218 * definition. 4bit tag is placed at 28 bit!
3219 */
3220 if ((res >> 28) == ALC880_HP_EVENT)
3221 alc880_medion_rim_automute(codec);
3222}
3223
4f5d1706 3224static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3225{
3226 struct alc_spec *spec = codec->spec;
3227
3228 spec->autocfg.hp_pins[0] = 0x14;
3229 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3230}
3231
cb53c626
TI
3232#ifdef CONFIG_SND_HDA_POWER_SAVE
3233static struct hda_amp_list alc880_loopbacks[] = {
3234 { 0x0b, HDA_INPUT, 0 },
3235 { 0x0b, HDA_INPUT, 1 },
3236 { 0x0b, HDA_INPUT, 2 },
3237 { 0x0b, HDA_INPUT, 3 },
3238 { 0x0b, HDA_INPUT, 4 },
3239 { } /* end */
3240};
3241
3242static struct hda_amp_list alc880_lg_loopbacks[] = {
3243 { 0x0b, HDA_INPUT, 1 },
3244 { 0x0b, HDA_INPUT, 6 },
3245 { 0x0b, HDA_INPUT, 7 },
3246 { } /* end */
3247};
3248#endif
3249
ae6b813a
TI
3250/*
3251 * Common callbacks
e9edcee0
TI
3252 */
3253
1da177e4
LT
3254static int alc_init(struct hda_codec *codec)
3255{
3256 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3257 unsigned int i;
3258
2c3bf9ab 3259 alc_fix_pll(codec);
4a79ba34 3260 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3261
e9edcee0
TI
3262 for (i = 0; i < spec->num_init_verbs; i++)
3263 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3264
3265 if (spec->init_hook)
3266 spec->init_hook(codec);
3267
1da177e4
LT
3268 return 0;
3269}
3270
ae6b813a
TI
3271static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3272{
3273 struct alc_spec *spec = codec->spec;
3274
3275 if (spec->unsol_event)
3276 spec->unsol_event(codec, res);
3277}
3278
cb53c626
TI
3279#ifdef CONFIG_SND_HDA_POWER_SAVE
3280static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3281{
3282 struct alc_spec *spec = codec->spec;
3283 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3284}
3285#endif
3286
1da177e4
LT
3287/*
3288 * Analog playback callbacks
3289 */
3290static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3291 struct hda_codec *codec,
c8b6bf9b 3292 struct snd_pcm_substream *substream)
1da177e4
LT
3293{
3294 struct alc_spec *spec = codec->spec;
9a08160b
TI
3295 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3296 hinfo);
1da177e4
LT
3297}
3298
3299static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3300 struct hda_codec *codec,
3301 unsigned int stream_tag,
3302 unsigned int format,
c8b6bf9b 3303 struct snd_pcm_substream *substream)
1da177e4
LT
3304{
3305 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3306 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3307 stream_tag, format, substream);
1da177e4
LT
3308}
3309
3310static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3311 struct hda_codec *codec,
c8b6bf9b 3312 struct snd_pcm_substream *substream)
1da177e4
LT
3313{
3314 struct alc_spec *spec = codec->spec;
3315 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3316}
3317
3318/*
3319 * Digital out
3320 */
3321static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3322 struct hda_codec *codec,
c8b6bf9b 3323 struct snd_pcm_substream *substream)
1da177e4
LT
3324{
3325 struct alc_spec *spec = codec->spec;
3326 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3327}
3328
6b97eb45
TI
3329static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3330 struct hda_codec *codec,
3331 unsigned int stream_tag,
3332 unsigned int format,
3333 struct snd_pcm_substream *substream)
3334{
3335 struct alc_spec *spec = codec->spec;
3336 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3337 stream_tag, format, substream);
3338}
3339
9b5f12e5
TI
3340static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3341 struct hda_codec *codec,
3342 struct snd_pcm_substream *substream)
3343{
3344 struct alc_spec *spec = codec->spec;
3345 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3346}
3347
1da177e4
LT
3348static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3349 struct hda_codec *codec,
c8b6bf9b 3350 struct snd_pcm_substream *substream)
1da177e4
LT
3351{
3352 struct alc_spec *spec = codec->spec;
3353 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3354}
3355
3356/*
3357 * Analog capture
3358 */
6330079f 3359static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3360 struct hda_codec *codec,
3361 unsigned int stream_tag,
3362 unsigned int format,
c8b6bf9b 3363 struct snd_pcm_substream *substream)
1da177e4
LT
3364{
3365 struct alc_spec *spec = codec->spec;
3366
6330079f 3367 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3368 stream_tag, 0, format);
3369 return 0;
3370}
3371
6330079f 3372static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3373 struct hda_codec *codec,
c8b6bf9b 3374 struct snd_pcm_substream *substream)
1da177e4
LT
3375{
3376 struct alc_spec *spec = codec->spec;
3377
888afa15
TI
3378 snd_hda_codec_cleanup_stream(codec,
3379 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3380 return 0;
3381}
3382
3383
3384/*
3385 */
3386static struct hda_pcm_stream alc880_pcm_analog_playback = {
3387 .substreams = 1,
3388 .channels_min = 2,
3389 .channels_max = 8,
e9edcee0 3390 /* NID is set in alc_build_pcms */
1da177e4
LT
3391 .ops = {
3392 .open = alc880_playback_pcm_open,
3393 .prepare = alc880_playback_pcm_prepare,
3394 .cleanup = alc880_playback_pcm_cleanup
3395 },
3396};
3397
3398static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3399 .substreams = 1,
3400 .channels_min = 2,
3401 .channels_max = 2,
3402 /* NID is set in alc_build_pcms */
3403};
3404
3405static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3406 .substreams = 1,
3407 .channels_min = 2,
3408 .channels_max = 2,
3409 /* NID is set in alc_build_pcms */
3410};
3411
3412static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3413 .substreams = 2, /* can be overridden */
1da177e4
LT
3414 .channels_min = 2,
3415 .channels_max = 2,
e9edcee0 3416 /* NID is set in alc_build_pcms */
1da177e4 3417 .ops = {
6330079f
TI
3418 .prepare = alc880_alt_capture_pcm_prepare,
3419 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3420 },
3421};
3422
3423static struct hda_pcm_stream alc880_pcm_digital_playback = {
3424 .substreams = 1,
3425 .channels_min = 2,
3426 .channels_max = 2,
3427 /* NID is set in alc_build_pcms */
3428 .ops = {
3429 .open = alc880_dig_playback_pcm_open,
6b97eb45 3430 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3431 .prepare = alc880_dig_playback_pcm_prepare,
3432 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3433 },
3434};
3435
3436static struct hda_pcm_stream alc880_pcm_digital_capture = {
3437 .substreams = 1,
3438 .channels_min = 2,
3439 .channels_max = 2,
3440 /* NID is set in alc_build_pcms */
3441};
3442
4c5186ed 3443/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3444static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3445 .substreams = 0,
3446 .channels_min = 0,
3447 .channels_max = 0,
3448};
3449
1da177e4
LT
3450static int alc_build_pcms(struct hda_codec *codec)
3451{
3452 struct alc_spec *spec = codec->spec;
3453 struct hda_pcm *info = spec->pcm_rec;
3454 int i;
3455
3456 codec->num_pcms = 1;
3457 codec->pcm_info = info;
3458
e64f14f4
TI
3459 if (spec->no_analog)
3460 goto skip_analog;
3461
812a2cca
TI
3462 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3463 "%s Analog", codec->chip_name);
1da177e4 3464 info->name = spec->stream_name_analog;
812a2cca 3465
4a471b7d 3466 if (spec->stream_analog_playback) {
da3cec35
TI
3467 if (snd_BUG_ON(!spec->multiout.dac_nids))
3468 return -EINVAL;
4a471b7d
TI
3469 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3470 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3471 }
3472 if (spec->stream_analog_capture) {
da3cec35
TI
3473 if (snd_BUG_ON(!spec->adc_nids))
3474 return -EINVAL;
4a471b7d
TI
3475 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3476 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3477 }
3478
3479 if (spec->channel_mode) {
3480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3481 for (i = 0; i < spec->num_channel_mode; i++) {
3482 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3483 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3484 }
1da177e4
LT
3485 }
3486 }
3487
e64f14f4 3488 skip_analog:
e08a007d 3489 /* SPDIF for stream index #1 */
1da177e4 3490 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3491 snprintf(spec->stream_name_digital,
3492 sizeof(spec->stream_name_digital),
3493 "%s Digital", codec->chip_name);
e08a007d 3494 codec->num_pcms = 2;
b25c9da1 3495 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3496 info = spec->pcm_rec + 1;
1da177e4 3497 info->name = spec->stream_name_digital;
8c441982
TI
3498 if (spec->dig_out_type)
3499 info->pcm_type = spec->dig_out_type;
3500 else
3501 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3502 if (spec->multiout.dig_out_nid &&
3503 spec->stream_digital_playback) {
1da177e4
LT
3504 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3505 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3506 }
4a471b7d
TI
3507 if (spec->dig_in_nid &&
3508 spec->stream_digital_capture) {
1da177e4
LT
3509 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3510 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3511 }
963f803f
TI
3512 /* FIXME: do we need this for all Realtek codec models? */
3513 codec->spdif_status_reset = 1;
1da177e4
LT
3514 }
3515
e64f14f4
TI
3516 if (spec->no_analog)
3517 return 0;
3518
e08a007d
TI
3519 /* If the use of more than one ADC is requested for the current
3520 * model, configure a second analog capture-only PCM.
3521 */
3522 /* Additional Analaog capture for index #2 */
6330079f
TI
3523 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3524 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3525 codec->num_pcms = 3;
c06134d7 3526 info = spec->pcm_rec + 2;
e08a007d 3527 info->name = spec->stream_name_analog;
6330079f
TI
3528 if (spec->alt_dac_nid) {
3529 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3530 *spec->stream_analog_alt_playback;
3531 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3532 spec->alt_dac_nid;
3533 } else {
3534 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3535 alc_pcm_null_stream;
3536 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3537 }
3538 if (spec->num_adc_nids > 1) {
3539 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3540 *spec->stream_analog_alt_capture;
3541 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3542 spec->adc_nids[1];
3543 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3544 spec->num_adc_nids - 1;
3545 } else {
3546 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3547 alc_pcm_null_stream;
3548 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3549 }
3550 }
3551
1da177e4
LT
3552 return 0;
3553}
3554
603c4019
TI
3555static void alc_free_kctls(struct hda_codec *codec)
3556{
3557 struct alc_spec *spec = codec->spec;
3558
3559 if (spec->kctls.list) {
3560 struct snd_kcontrol_new *kctl = spec->kctls.list;
3561 int i;
3562 for (i = 0; i < spec->kctls.used; i++)
3563 kfree(kctl[i].name);
3564 }
3565 snd_array_free(&spec->kctls);
3566}
3567
1da177e4
LT
3568static void alc_free(struct hda_codec *codec)
3569{
e9edcee0 3570 struct alc_spec *spec = codec->spec;
e9edcee0 3571
f12ab1e0 3572 if (!spec)
e9edcee0
TI
3573 return;
3574
603c4019 3575 alc_free_kctls(codec);
e9edcee0 3576 kfree(spec);
680cd536 3577 snd_hda_detach_beep_device(codec);
1da177e4
LT
3578}
3579
e044c39a 3580#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3581static int alc_resume(struct hda_codec *codec)
3582{
e044c39a
TI
3583 codec->patch_ops.init(codec);
3584 snd_hda_codec_resume_amp(codec);
3585 snd_hda_codec_resume_cache(codec);
3586 return 0;
3587}
e044c39a
TI
3588#endif
3589
1da177e4
LT
3590/*
3591 */
3592static struct hda_codec_ops alc_patch_ops = {
3593 .build_controls = alc_build_controls,
3594 .build_pcms = alc_build_pcms,
3595 .init = alc_init,
3596 .free = alc_free,
ae6b813a 3597 .unsol_event = alc_unsol_event,
e044c39a
TI
3598#ifdef SND_HDA_NEEDS_RESUME
3599 .resume = alc_resume,
3600#endif
cb53c626
TI
3601#ifdef CONFIG_SND_HDA_POWER_SAVE
3602 .check_power_status = alc_check_power_status,
3603#endif
1da177e4
LT
3604};
3605
2fa522be
TI
3606
3607/*
3608 * Test configuration for debugging
3609 *
3610 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3611 * enum controls.
3612 */
3613#ifdef CONFIG_SND_DEBUG
3614static hda_nid_t alc880_test_dac_nids[4] = {
3615 0x02, 0x03, 0x04, 0x05
3616};
3617
3618static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3619 .num_items = 7,
2fa522be
TI
3620 .items = {
3621 { "In-1", 0x0 },
3622 { "In-2", 0x1 },
3623 { "In-3", 0x2 },
3624 { "In-4", 0x3 },
3625 { "CD", 0x4 },
ae6b813a
TI
3626 { "Front", 0x5 },
3627 { "Surround", 0x6 },
2fa522be
TI
3628 },
3629};
3630
d2a6d7dc 3631static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3632 { 2, NULL },
fd2c326d 3633 { 4, NULL },
2fa522be 3634 { 6, NULL },
fd2c326d 3635 { 8, NULL },
2fa522be
TI
3636};
3637
9c7f852e
TI
3638static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3639 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3640{
3641 static char *texts[] = {
3642 "N/A", "Line Out", "HP Out",
3643 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3644 };
3645 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3646 uinfo->count = 1;
3647 uinfo->value.enumerated.items = 8;
3648 if (uinfo->value.enumerated.item >= 8)
3649 uinfo->value.enumerated.item = 7;
3650 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3651 return 0;
3652}
3653
9c7f852e
TI
3654static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3655 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3656{
3657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3658 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3659 unsigned int pin_ctl, item = 0;
3660
3661 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3662 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3663 if (pin_ctl & AC_PINCTL_OUT_EN) {
3664 if (pin_ctl & AC_PINCTL_HP_EN)
3665 item = 2;
3666 else
3667 item = 1;
3668 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3669 switch (pin_ctl & AC_PINCTL_VREFEN) {
3670 case AC_PINCTL_VREF_HIZ: item = 3; break;
3671 case AC_PINCTL_VREF_50: item = 4; break;
3672 case AC_PINCTL_VREF_GRD: item = 5; break;
3673 case AC_PINCTL_VREF_80: item = 6; break;
3674 case AC_PINCTL_VREF_100: item = 7; break;
3675 }
3676 }
3677 ucontrol->value.enumerated.item[0] = item;
3678 return 0;
3679}
3680
9c7f852e
TI
3681static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3682 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3683{
3684 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3685 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3686 static unsigned int ctls[] = {
3687 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3688 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3689 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3690 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3691 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3692 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3693 };
3694 unsigned int old_ctl, new_ctl;
3695
3696 old_ctl = snd_hda_codec_read(codec, nid, 0,
3697 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3698 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3699 if (old_ctl != new_ctl) {
82beb8fd
TI
3700 int val;
3701 snd_hda_codec_write_cache(codec, nid, 0,
3702 AC_VERB_SET_PIN_WIDGET_CONTROL,
3703 new_ctl);
47fd830a
TI
3704 val = ucontrol->value.enumerated.item[0] >= 3 ?
3705 HDA_AMP_MUTE : 0;
3706 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3707 HDA_AMP_MUTE, val);
2fa522be
TI
3708 return 1;
3709 }
3710 return 0;
3711}
3712
9c7f852e
TI
3713static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3714 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3715{
3716 static char *texts[] = {
3717 "Front", "Surround", "CLFE", "Side"
3718 };
3719 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3720 uinfo->count = 1;
3721 uinfo->value.enumerated.items = 4;
3722 if (uinfo->value.enumerated.item >= 4)
3723 uinfo->value.enumerated.item = 3;
3724 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3725 return 0;
3726}
3727
9c7f852e
TI
3728static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3729 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3730{
3731 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3732 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3733 unsigned int sel;
3734
3735 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3736 ucontrol->value.enumerated.item[0] = sel & 3;
3737 return 0;
3738}
3739
9c7f852e
TI
3740static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3741 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3742{
3743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3744 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3745 unsigned int sel;
3746
3747 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3748 if (ucontrol->value.enumerated.item[0] != sel) {
3749 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3750 snd_hda_codec_write_cache(codec, nid, 0,
3751 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3752 return 1;
3753 }
3754 return 0;
3755}
3756
3757#define PIN_CTL_TEST(xname,nid) { \
3758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3759 .name = xname, \
3760 .info = alc_test_pin_ctl_info, \
3761 .get = alc_test_pin_ctl_get, \
3762 .put = alc_test_pin_ctl_put, \
3763 .private_value = nid \
3764 }
3765
3766#define PIN_SRC_TEST(xname,nid) { \
3767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3768 .name = xname, \
3769 .info = alc_test_pin_src_info, \
3770 .get = alc_test_pin_src_get, \
3771 .put = alc_test_pin_src_put, \
3772 .private_value = nid \
3773 }
3774
c8b6bf9b 3775static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3777 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3778 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3779 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3780 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3781 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3782 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3783 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3784 PIN_CTL_TEST("Front Pin Mode", 0x14),
3785 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3786 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3787 PIN_CTL_TEST("Side Pin Mode", 0x17),
3788 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3789 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3790 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3791 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3792 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3793 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3794 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3795 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3796 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3797 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3798 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3799 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3800 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3801 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3802 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3803 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3804 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3805 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3806 {
3807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3808 .name = "Channel Mode",
df694daa
KY
3809 .info = alc_ch_mode_info,
3810 .get = alc_ch_mode_get,
3811 .put = alc_ch_mode_put,
2fa522be
TI
3812 },
3813 { } /* end */
3814};
3815
3816static struct hda_verb alc880_test_init_verbs[] = {
3817 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3818 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3820 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3821 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3822 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3823 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3824 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3825 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3826 /* Vol output for 0x0c-0x0f */
05acb863
TI
3827 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3828 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3829 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3830 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3831 /* Set output pins 0x14-0x17 */
05acb863
TI
3832 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3835 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3836 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3837 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3839 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3840 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3841 /* Set input pins 0x18-0x1c */
16ded525
TI
3842 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3844 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3846 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3847 /* Mute input pins 0x18-0x1b */
05acb863
TI
3848 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3849 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3850 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3851 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3852 /* ADC set up */
05acb863 3853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3854 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3855 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3856 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3858 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3859 /* Analog input/passthru */
3860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3861 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3863 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3864 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3865 { }
3866};
3867#endif
3868
1da177e4
LT
3869/*
3870 */
3871
f5fcc13c
TI
3872static const char *alc880_models[ALC880_MODEL_LAST] = {
3873 [ALC880_3ST] = "3stack",
3874 [ALC880_TCL_S700] = "tcl",
3875 [ALC880_3ST_DIG] = "3stack-digout",
3876 [ALC880_CLEVO] = "clevo",
3877 [ALC880_5ST] = "5stack",
3878 [ALC880_5ST_DIG] = "5stack-digout",
3879 [ALC880_W810] = "w810",
3880 [ALC880_Z71V] = "z71v",
3881 [ALC880_6ST] = "6stack",
3882 [ALC880_6ST_DIG] = "6stack-digout",
3883 [ALC880_ASUS] = "asus",
3884 [ALC880_ASUS_W1V] = "asus-w1v",
3885 [ALC880_ASUS_DIG] = "asus-dig",
3886 [ALC880_ASUS_DIG2] = "asus-dig2",
3887 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3888 [ALC880_UNIWILL_P53] = "uniwill-p53",
3889 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3890 [ALC880_F1734] = "F1734",
3891 [ALC880_LG] = "lg",
3892 [ALC880_LG_LW] = "lg-lw",
df99cd33 3893 [ALC880_MEDION_RIM] = "medion",
2fa522be 3894#ifdef CONFIG_SND_DEBUG
f5fcc13c 3895 [ALC880_TEST] = "test",
2fa522be 3896#endif
f5fcc13c
TI
3897 [ALC880_AUTO] = "auto",
3898};
3899
3900static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3901 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3902 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3903 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3904 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3905 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3906 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3907 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3908 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3909 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3910 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3911 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3912 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3913 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3914 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3915 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3916 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3917 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3918 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3919 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3920 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3921 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3922 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3923 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3924 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3925 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 3926 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3927 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3928 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3929 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3930 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3931 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3932 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3933 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3934 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3935 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3936 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3937 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3938 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3939 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3940 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3941 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3942 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3943 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3944 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3945 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3946 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3947 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3948 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3949 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3950 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3951 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3952 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3953 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3954 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3955 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3956 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3957 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3958 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3959 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3960 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3961 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3962 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3963 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3964 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3965 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3966 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3967 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3968 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
3969 /* default Intel */
3970 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
3971 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3972 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3973 {}
3974};
3975
16ded525 3976/*
df694daa 3977 * ALC880 codec presets
16ded525 3978 */
16ded525
TI
3979static struct alc_config_preset alc880_presets[] = {
3980 [ALC880_3ST] = {
e9edcee0 3981 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3982 .init_verbs = { alc880_volume_init_verbs,
3983 alc880_pin_3stack_init_verbs },
16ded525 3984 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3985 .dac_nids = alc880_dac_nids,
16ded525
TI
3986 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3987 .channel_mode = alc880_threestack_modes,
4e195a7b 3988 .need_dac_fix = 1,
16ded525
TI
3989 .input_mux = &alc880_capture_source,
3990 },
3991 [ALC880_3ST_DIG] = {
e9edcee0 3992 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3993 .init_verbs = { alc880_volume_init_verbs,
3994 alc880_pin_3stack_init_verbs },
16ded525 3995 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3996 .dac_nids = alc880_dac_nids,
3997 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3998 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3999 .channel_mode = alc880_threestack_modes,
4e195a7b 4000 .need_dac_fix = 1,
16ded525
TI
4001 .input_mux = &alc880_capture_source,
4002 },
df694daa
KY
4003 [ALC880_TCL_S700] = {
4004 .mixers = { alc880_tcl_s700_mixer },
4005 .init_verbs = { alc880_volume_init_verbs,
4006 alc880_pin_tcl_S700_init_verbs,
4007 alc880_gpio2_init_verbs },
4008 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4009 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4010 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4011 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4012 .hp_nid = 0x03,
4013 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4014 .channel_mode = alc880_2_jack_modes,
4015 .input_mux = &alc880_capture_source,
4016 },
16ded525 4017 [ALC880_5ST] = {
f12ab1e0
TI
4018 .mixers = { alc880_three_stack_mixer,
4019 alc880_five_stack_mixer},
4020 .init_verbs = { alc880_volume_init_verbs,
4021 alc880_pin_5stack_init_verbs },
16ded525
TI
4022 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4023 .dac_nids = alc880_dac_nids,
16ded525
TI
4024 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4025 .channel_mode = alc880_fivestack_modes,
4026 .input_mux = &alc880_capture_source,
4027 },
4028 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4029 .mixers = { alc880_three_stack_mixer,
4030 alc880_five_stack_mixer },
4031 .init_verbs = { alc880_volume_init_verbs,
4032 alc880_pin_5stack_init_verbs },
16ded525
TI
4033 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4034 .dac_nids = alc880_dac_nids,
4035 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4036 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4037 .channel_mode = alc880_fivestack_modes,
4038 .input_mux = &alc880_capture_source,
4039 },
b6482d48
TI
4040 [ALC880_6ST] = {
4041 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4042 .init_verbs = { alc880_volume_init_verbs,
4043 alc880_pin_6stack_init_verbs },
b6482d48
TI
4044 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4045 .dac_nids = alc880_6st_dac_nids,
4046 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4047 .channel_mode = alc880_sixstack_modes,
4048 .input_mux = &alc880_6stack_capture_source,
4049 },
16ded525 4050 [ALC880_6ST_DIG] = {
e9edcee0 4051 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4052 .init_verbs = { alc880_volume_init_verbs,
4053 alc880_pin_6stack_init_verbs },
16ded525
TI
4054 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4055 .dac_nids = alc880_6st_dac_nids,
4056 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4057 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4058 .channel_mode = alc880_sixstack_modes,
4059 .input_mux = &alc880_6stack_capture_source,
4060 },
4061 [ALC880_W810] = {
e9edcee0 4062 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4063 .init_verbs = { alc880_volume_init_verbs,
4064 alc880_pin_w810_init_verbs,
b0af0de5 4065 alc880_gpio2_init_verbs },
16ded525
TI
4066 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4067 .dac_nids = alc880_w810_dac_nids,
4068 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4069 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4070 .channel_mode = alc880_w810_modes,
4071 .input_mux = &alc880_capture_source,
4072 },
4073 [ALC880_Z71V] = {
e9edcee0 4074 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4075 .init_verbs = { alc880_volume_init_verbs,
4076 alc880_pin_z71v_init_verbs },
16ded525
TI
4077 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4078 .dac_nids = alc880_z71v_dac_nids,
4079 .dig_out_nid = ALC880_DIGOUT_NID,
4080 .hp_nid = 0x03,
e9edcee0
TI
4081 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4082 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4083 .input_mux = &alc880_capture_source,
4084 },
4085 [ALC880_F1734] = {
e9edcee0 4086 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4087 .init_verbs = { alc880_volume_init_verbs,
4088 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4089 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4090 .dac_nids = alc880_f1734_dac_nids,
4091 .hp_nid = 0x02,
4092 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4093 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4094 .input_mux = &alc880_f1734_capture_source,
4095 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4096 .setup = alc880_uniwill_p53_setup,
4097 .init_hook = alc_automute_amp,
16ded525
TI
4098 },
4099 [ALC880_ASUS] = {
e9edcee0 4100 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4101 .init_verbs = { alc880_volume_init_verbs,
4102 alc880_pin_asus_init_verbs,
e9edcee0
TI
4103 alc880_gpio1_init_verbs },
4104 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4105 .dac_nids = alc880_asus_dac_nids,
4106 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4107 .channel_mode = alc880_asus_modes,
4e195a7b 4108 .need_dac_fix = 1,
16ded525
TI
4109 .input_mux = &alc880_capture_source,
4110 },
4111 [ALC880_ASUS_DIG] = {
e9edcee0 4112 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4113 .init_verbs = { alc880_volume_init_verbs,
4114 alc880_pin_asus_init_verbs,
e9edcee0
TI
4115 alc880_gpio1_init_verbs },
4116 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4117 .dac_nids = alc880_asus_dac_nids,
16ded525 4118 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4119 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4120 .channel_mode = alc880_asus_modes,
4e195a7b 4121 .need_dac_fix = 1,
16ded525
TI
4122 .input_mux = &alc880_capture_source,
4123 },
df694daa
KY
4124 [ALC880_ASUS_DIG2] = {
4125 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4126 .init_verbs = { alc880_volume_init_verbs,
4127 alc880_pin_asus_init_verbs,
df694daa
KY
4128 alc880_gpio2_init_verbs }, /* use GPIO2 */
4129 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4130 .dac_nids = alc880_asus_dac_nids,
4131 .dig_out_nid = ALC880_DIGOUT_NID,
4132 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4133 .channel_mode = alc880_asus_modes,
4e195a7b 4134 .need_dac_fix = 1,
df694daa
KY
4135 .input_mux = &alc880_capture_source,
4136 },
16ded525 4137 [ALC880_ASUS_W1V] = {
e9edcee0 4138 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4139 .init_verbs = { alc880_volume_init_verbs,
4140 alc880_pin_asus_init_verbs,
e9edcee0
TI
4141 alc880_gpio1_init_verbs },
4142 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4143 .dac_nids = alc880_asus_dac_nids,
16ded525 4144 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4145 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4146 .channel_mode = alc880_asus_modes,
4e195a7b 4147 .need_dac_fix = 1,
16ded525
TI
4148 .input_mux = &alc880_capture_source,
4149 },
4150 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4151 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4152 .init_verbs = { alc880_volume_init_verbs,
4153 alc880_pin_asus_init_verbs },
e9edcee0
TI
4154 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4155 .dac_nids = alc880_asus_dac_nids,
16ded525 4156 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4157 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4158 .channel_mode = alc880_asus_modes,
4e195a7b 4159 .need_dac_fix = 1,
16ded525
TI
4160 .input_mux = &alc880_capture_source,
4161 },
ccc656ce
KY
4162 [ALC880_UNIWILL] = {
4163 .mixers = { alc880_uniwill_mixer },
4164 .init_verbs = { alc880_volume_init_verbs,
4165 alc880_uniwill_init_verbs },
4166 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4167 .dac_nids = alc880_asus_dac_nids,
4168 .dig_out_nid = ALC880_DIGOUT_NID,
4169 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4170 .channel_mode = alc880_threestack_modes,
4171 .need_dac_fix = 1,
4172 .input_mux = &alc880_capture_source,
4173 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4174 .setup = alc880_uniwill_setup,
a9fd4f3f 4175 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4176 },
4177 [ALC880_UNIWILL_P53] = {
4178 .mixers = { alc880_uniwill_p53_mixer },
4179 .init_verbs = { alc880_volume_init_verbs,
4180 alc880_uniwill_p53_init_verbs },
4181 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4182 .dac_nids = alc880_asus_dac_nids,
4183 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4184 .channel_mode = alc880_threestack_modes,
4185 .input_mux = &alc880_capture_source,
4186 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4187 .setup = alc880_uniwill_p53_setup,
4188 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4189 },
4190 [ALC880_FUJITSU] = {
45bdd1c1 4191 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4192 .init_verbs = { alc880_volume_init_verbs,
4193 alc880_uniwill_p53_init_verbs,
4194 alc880_beep_init_verbs },
4195 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4196 .dac_nids = alc880_dac_nids,
d53d7d9e 4197 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4198 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4199 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4200 .input_mux = &alc880_capture_source,
4201 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4202 .setup = alc880_uniwill_p53_setup,
4203 .init_hook = alc_automute_amp,
ccc656ce 4204 },
df694daa
KY
4205 [ALC880_CLEVO] = {
4206 .mixers = { alc880_three_stack_mixer },
4207 .init_verbs = { alc880_volume_init_verbs,
4208 alc880_pin_clevo_init_verbs },
4209 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4210 .dac_nids = alc880_dac_nids,
4211 .hp_nid = 0x03,
4212 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4213 .channel_mode = alc880_threestack_modes,
4e195a7b 4214 .need_dac_fix = 1,
df694daa
KY
4215 .input_mux = &alc880_capture_source,
4216 },
ae6b813a
TI
4217 [ALC880_LG] = {
4218 .mixers = { alc880_lg_mixer },
4219 .init_verbs = { alc880_volume_init_verbs,
4220 alc880_lg_init_verbs },
4221 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4222 .dac_nids = alc880_lg_dac_nids,
4223 .dig_out_nid = ALC880_DIGOUT_NID,
4224 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4225 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4226 .need_dac_fix = 1,
ae6b813a 4227 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4228 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4229 .setup = alc880_lg_setup,
4230 .init_hook = alc_automute_amp,
cb53c626
TI
4231#ifdef CONFIG_SND_HDA_POWER_SAVE
4232 .loopbacks = alc880_lg_loopbacks,
4233#endif
ae6b813a 4234 },
d681518a
TI
4235 [ALC880_LG_LW] = {
4236 .mixers = { alc880_lg_lw_mixer },
4237 .init_verbs = { alc880_volume_init_verbs,
4238 alc880_lg_lw_init_verbs },
0a8c5da3 4239 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4240 .dac_nids = alc880_dac_nids,
4241 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4242 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4243 .channel_mode = alc880_lg_lw_modes,
d681518a 4244 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4245 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4246 .setup = alc880_lg_lw_setup,
4247 .init_hook = alc_automute_amp,
d681518a 4248 },
df99cd33
TI
4249 [ALC880_MEDION_RIM] = {
4250 .mixers = { alc880_medion_rim_mixer },
4251 .init_verbs = { alc880_volume_init_verbs,
4252 alc880_medion_rim_init_verbs,
4253 alc_gpio2_init_verbs },
4254 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4255 .dac_nids = alc880_dac_nids,
4256 .dig_out_nid = ALC880_DIGOUT_NID,
4257 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4258 .channel_mode = alc880_2_jack_modes,
4259 .input_mux = &alc880_medion_rim_capture_source,
4260 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4261 .setup = alc880_medion_rim_setup,
4262 .init_hook = alc880_medion_rim_automute,
df99cd33 4263 },
16ded525
TI
4264#ifdef CONFIG_SND_DEBUG
4265 [ALC880_TEST] = {
e9edcee0
TI
4266 .mixers = { alc880_test_mixer },
4267 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4268 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4269 .dac_nids = alc880_test_dac_nids,
4270 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4271 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4272 .channel_mode = alc880_test_modes,
4273 .input_mux = &alc880_test_capture_source,
4274 },
4275#endif
4276};
4277
e9edcee0
TI
4278/*
4279 * Automatic parse of I/O pins from the BIOS configuration
4280 */
4281
e9edcee0
TI
4282enum {
4283 ALC_CTL_WIDGET_VOL,
4284 ALC_CTL_WIDGET_MUTE,
4285 ALC_CTL_BIND_MUTE,
4286};
c8b6bf9b 4287static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4288 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4289 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4290 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4291};
4292
4293/* add dynamic controls */
f12ab1e0
TI
4294static int add_control(struct alc_spec *spec, int type, const char *name,
4295 unsigned long val)
e9edcee0 4296{
c8b6bf9b 4297 struct snd_kcontrol_new *knew;
e9edcee0 4298
603c4019
TI
4299 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4300 knew = snd_array_new(&spec->kctls);
4301 if (!knew)
4302 return -ENOMEM;
e9edcee0 4303 *knew = alc880_control_templates[type];
543537bd 4304 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4305 if (!knew->name)
e9edcee0
TI
4306 return -ENOMEM;
4307 knew->private_value = val;
e9edcee0
TI
4308 return 0;
4309}
4310
4311#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4312#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4313#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4314#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4315#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4316#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4317#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4318#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4319#define ALC880_PIN_CD_NID 0x1c
4320
4321/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4322static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4323 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4324{
4325 hda_nid_t nid;
4326 int assigned[4];
4327 int i, j;
4328
4329 memset(assigned, 0, sizeof(assigned));
b0af0de5 4330 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4331
4332 /* check the pins hardwired to audio widget */
4333 for (i = 0; i < cfg->line_outs; i++) {
4334 nid = cfg->line_out_pins[i];
4335 if (alc880_is_fixed_pin(nid)) {
4336 int idx = alc880_fixed_pin_idx(nid);
5014f193 4337 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4338 assigned[idx] = 1;
4339 }
4340 }
4341 /* left pins can be connect to any audio widget */
4342 for (i = 0; i < cfg->line_outs; i++) {
4343 nid = cfg->line_out_pins[i];
4344 if (alc880_is_fixed_pin(nid))
4345 continue;
4346 /* search for an empty channel */
4347 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4348 if (!assigned[j]) {
4349 spec->multiout.dac_nids[i] =
4350 alc880_idx_to_dac(j);
e9edcee0
TI
4351 assigned[j] = 1;
4352 break;
4353 }
4354 }
4355 }
4356 spec->multiout.num_dacs = cfg->line_outs;
4357 return 0;
4358}
4359
4360/* add playback controls from the parsed DAC table */
df694daa
KY
4361static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4362 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4363{
4364 char name[32];
f12ab1e0
TI
4365 static const char *chname[4] = {
4366 "Front", "Surround", NULL /*CLFE*/, "Side"
4367 };
e9edcee0
TI
4368 hda_nid_t nid;
4369 int i, err;
4370
4371 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4372 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4373 continue;
4374 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4375 if (i == 2) {
4376 /* Center/LFE */
f12ab1e0
TI
4377 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4378 "Center Playback Volume",
4379 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4380 HDA_OUTPUT));
4381 if (err < 0)
e9edcee0 4382 return err;
f12ab1e0
TI
4383 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4384 "LFE Playback Volume",
4385 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4386 HDA_OUTPUT));
4387 if (err < 0)
e9edcee0 4388 return err;
f12ab1e0
TI
4389 err = add_control(spec, ALC_CTL_BIND_MUTE,
4390 "Center Playback Switch",
4391 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4392 HDA_INPUT));
4393 if (err < 0)
e9edcee0 4394 return err;
f12ab1e0
TI
4395 err = add_control(spec, ALC_CTL_BIND_MUTE,
4396 "LFE Playback Switch",
4397 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4398 HDA_INPUT));
4399 if (err < 0)
e9edcee0
TI
4400 return err;
4401 } else {
cb162b6b
TI
4402 const char *pfx;
4403 if (cfg->line_outs == 1 &&
4404 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4405 pfx = "Speaker";
4406 else
4407 pfx = chname[i];
4408 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4409 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4410 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4411 HDA_OUTPUT));
4412 if (err < 0)
e9edcee0 4413 return err;
cb162b6b 4414 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4415 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4416 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4417 HDA_INPUT));
4418 if (err < 0)
e9edcee0
TI
4419 return err;
4420 }
4421 }
e9edcee0
TI
4422 return 0;
4423}
4424
8d88bc3d
TI
4425/* add playback controls for speaker and HP outputs */
4426static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4427 const char *pfx)
e9edcee0
TI
4428{
4429 hda_nid_t nid;
4430 int err;
8d88bc3d 4431 char name[32];
e9edcee0 4432
f12ab1e0 4433 if (!pin)
e9edcee0
TI
4434 return 0;
4435
4436 if (alc880_is_fixed_pin(pin)) {
4437 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4438 /* specify the DAC as the extra output */
f12ab1e0 4439 if (!spec->multiout.hp_nid)
e9edcee0 4440 spec->multiout.hp_nid = nid;
82bc955f
TI
4441 else
4442 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4443 /* control HP volume/switch on the output mixer amp */
4444 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 4445 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4446 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4447 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4448 if (err < 0)
e9edcee0 4449 return err;
8d88bc3d 4450 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4451 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4452 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4453 if (err < 0)
e9edcee0
TI
4454 return err;
4455 } else if (alc880_is_multi_pin(pin)) {
4456 /* set manual connection */
e9edcee0 4457 /* we have only a switch on HP-out PIN */
8d88bc3d 4458 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4459 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4460 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4461 if (err < 0)
e9edcee0
TI
4462 return err;
4463 }
4464 return 0;
4465}
4466
4467/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4468static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4469 const char *ctlname,
df694daa 4470 int idx, hda_nid_t mix_nid)
e9edcee0
TI
4471{
4472 char name[32];
df694daa 4473 int err;
e9edcee0
TI
4474
4475 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
4476 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4477 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4478 if (err < 0)
e9edcee0
TI
4479 return err;
4480 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
4481 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4482 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4483 if (err < 0)
e9edcee0
TI
4484 return err;
4485 return 0;
4486}
4487
05f5f477
TI
4488static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4489{
4490 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4491 return (pincap & AC_PINCAP_IN) != 0;
4492}
4493
e9edcee0 4494/* create playback/capture controls for input pins */
05f5f477
TI
4495static int alc_auto_create_input_ctls(struct hda_codec *codec,
4496 const struct auto_pin_cfg *cfg,
4497 hda_nid_t mixer,
4498 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4499{
05f5f477 4500 struct alc_spec *spec = codec->spec;
61b9b9b1 4501 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4502 int i, err, idx;
e9edcee0
TI
4503
4504 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4505 hda_nid_t pin;
4506
4507 pin = cfg->input_pins[i];
4508 if (!alc_is_input_pin(codec, pin))
4509 continue;
4510
4511 if (mixer) {
4512 idx = get_connection_index(codec, mixer, pin);
4513 if (idx >= 0) {
4514 err = new_analog_input(spec, pin,
4515 auto_pin_cfg_labels[i],
4516 idx, mixer);
4517 if (err < 0)
4518 return err;
4519 }
4520 }
4521
4522 if (!cap1)
4523 continue;
4524 idx = get_connection_index(codec, cap1, pin);
4525 if (idx < 0 && cap2)
4526 idx = get_connection_index(codec, cap2, pin);
4527 if (idx >= 0) {
f12ab1e0
TI
4528 imux->items[imux->num_items].label =
4529 auto_pin_cfg_labels[i];
05f5f477 4530 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4531 imux->num_items++;
4532 }
4533 }
4534 return 0;
4535}
4536
05f5f477
TI
4537static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4538 const struct auto_pin_cfg *cfg)
4539{
4540 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4541}
4542
f6c7e546
TI
4543static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4544 unsigned int pin_type)
4545{
4546 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4547 pin_type);
4548 /* unmute pin */
d260cdf6
TI
4549 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4550 AMP_OUT_UNMUTE);
f6c7e546
TI
4551}
4552
df694daa
KY
4553static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4554 hda_nid_t nid, int pin_type,
e9edcee0
TI
4555 int dac_idx)
4556{
f6c7e546 4557 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4558 /* need the manual connection? */
4559 if (alc880_is_multi_pin(nid)) {
4560 struct alc_spec *spec = codec->spec;
4561 int idx = alc880_multi_pin_idx(nid);
4562 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4563 AC_VERB_SET_CONNECT_SEL,
4564 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4565 }
4566}
4567
baba8ee9
TI
4568static int get_pin_type(int line_out_type)
4569{
4570 if (line_out_type == AUTO_PIN_HP_OUT)
4571 return PIN_HP;
4572 else
4573 return PIN_OUT;
4574}
4575
e9edcee0
TI
4576static void alc880_auto_init_multi_out(struct hda_codec *codec)
4577{
4578 struct alc_spec *spec = codec->spec;
4579 int i;
ea1fb29a 4580
e9edcee0
TI
4581 for (i = 0; i < spec->autocfg.line_outs; i++) {
4582 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4583 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4584 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4585 }
4586}
4587
8d88bc3d 4588static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4589{
4590 struct alc_spec *spec = codec->spec;
4591 hda_nid_t pin;
4592
82bc955f 4593 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4594 if (pin) /* connect to front */
4595 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4596 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4597 if (pin) /* connect to front */
4598 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4599}
4600
4601static void alc880_auto_init_analog_input(struct hda_codec *codec)
4602{
4603 struct alc_spec *spec = codec->spec;
4604 int i;
4605
4606 for (i = 0; i < AUTO_PIN_LAST; i++) {
4607 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 4608 if (alc_is_input_pin(codec, nid)) {
23f0c048 4609 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4610 if (nid != ALC880_PIN_CD_NID &&
4611 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4612 snd_hda_codec_write(codec, nid, 0,
4613 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4614 AMP_OUT_MUTE);
4615 }
4616 }
4617}
4618
4619/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4620/* return 1 if successful, 0 if the proper config is not found,
4621 * or a negative error code
4622 */
e9edcee0
TI
4623static int alc880_parse_auto_config(struct hda_codec *codec)
4624{
4625 struct alc_spec *spec = codec->spec;
6a05ac4a 4626 int i, err;
df694daa 4627 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4628
f12ab1e0
TI
4629 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4630 alc880_ignore);
4631 if (err < 0)
e9edcee0 4632 return err;
f12ab1e0 4633 if (!spec->autocfg.line_outs)
e9edcee0 4634 return 0; /* can't find valid BIOS pin config */
df694daa 4635
f12ab1e0
TI
4636 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4637 if (err < 0)
4638 return err;
4639 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4640 if (err < 0)
4641 return err;
4642 err = alc880_auto_create_extra_out(spec,
4643 spec->autocfg.speaker_pins[0],
4644 "Speaker");
4645 if (err < 0)
4646 return err;
4647 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4648 "Headphone");
4649 if (err < 0)
4650 return err;
05f5f477 4651 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 4652 if (err < 0)
e9edcee0
TI
4653 return err;
4654
4655 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4656
6a05ac4a
TI
4657 /* check multiple SPDIF-out (for recent codecs) */
4658 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4659 hda_nid_t dig_nid;
4660 err = snd_hda_get_connections(codec,
4661 spec->autocfg.dig_out_pins[i],
4662 &dig_nid, 1);
4663 if (err < 0)
4664 continue;
4665 if (!i)
4666 spec->multiout.dig_out_nid = dig_nid;
4667 else {
4668 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4669 spec->slave_dig_outs[i - 1] = dig_nid;
4670 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4671 break;
4672 }
4673 }
e9edcee0
TI
4674 if (spec->autocfg.dig_in_pin)
4675 spec->dig_in_nid = ALC880_DIGIN_NID;
4676
603c4019 4677 if (spec->kctls.list)
d88897ea 4678 add_mixer(spec, spec->kctls.list);
e9edcee0 4679
d88897ea 4680 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4681
a1e8d2da 4682 spec->num_mux_defs = 1;
61b9b9b1 4683 spec->input_mux = &spec->private_imux[0];
e9edcee0 4684
4a79ba34
TI
4685 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4686
e9edcee0
TI
4687 return 1;
4688}
4689
ae6b813a
TI
4690/* additional initialization for auto-configuration model */
4691static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4692{
f6c7e546 4693 struct alc_spec *spec = codec->spec;
e9edcee0 4694 alc880_auto_init_multi_out(codec);
8d88bc3d 4695 alc880_auto_init_extra_out(codec);
e9edcee0 4696 alc880_auto_init_analog_input(codec);
f6c7e546 4697 if (spec->unsol_event)
7fb0d78f 4698 alc_inithook(codec);
e9edcee0
TI
4699}
4700
b59bdf3b
TI
4701/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4702 * one of two digital mic pins, e.g. on ALC272
4703 */
4704static void fixup_automic_adc(struct hda_codec *codec)
4705{
4706 struct alc_spec *spec = codec->spec;
4707 int i;
4708
4709 for (i = 0; i < spec->num_adc_nids; i++) {
4710 hda_nid_t cap = spec->capsrc_nids ?
4711 spec->capsrc_nids[i] : spec->adc_nids[i];
4712 int iidx, eidx;
4713
4714 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4715 if (iidx < 0)
4716 continue;
4717 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4718 if (eidx < 0)
4719 continue;
4720 spec->int_mic.mux_idx = iidx;
4721 spec->ext_mic.mux_idx = eidx;
4722 if (spec->capsrc_nids)
4723 spec->capsrc_nids += i;
4724 spec->adc_nids += i;
4725 spec->num_adc_nids = 1;
4726 return;
4727 }
4728 snd_printd(KERN_INFO "hda_codec: %s: "
4729 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4730 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4731 spec->auto_mic = 0; /* disable auto-mic to be sure */
4732}
4733
4734static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 4735{
b59bdf3b 4736 struct alc_spec *spec = codec->spec;
a23b688f
TI
4737 static struct snd_kcontrol_new *caps[2][3] = {
4738 { alc_capture_mixer_nosrc1,
4739 alc_capture_mixer_nosrc2,
4740 alc_capture_mixer_nosrc3 },
4741 { alc_capture_mixer1,
4742 alc_capture_mixer2,
4743 alc_capture_mixer3 },
f9e336f6 4744 };
a23b688f
TI
4745 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4746 int mux;
2a22d3f8
TI
4747 if (spec->auto_mic) {
4748 mux = 0;
b59bdf3b 4749 fixup_automic_adc(codec);
2a22d3f8 4750 } else if (spec->input_mux && spec->input_mux->num_items > 1)
a23b688f
TI
4751 mux = 1;
4752 else
4753 mux = 0;
4754 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4755 }
f9e336f6
TI
4756}
4757
45bdd1c1
TI
4758#define set_beep_amp(spec, nid, idx, dir) \
4759 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4760
4761/*
4762 * OK, here we have finally the patch for ALC880
4763 */
4764
1da177e4
LT
4765static int patch_alc880(struct hda_codec *codec)
4766{
4767 struct alc_spec *spec;
4768 int board_config;
df694daa 4769 int err;
1da177e4 4770
e560d8d8 4771 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4772 if (spec == NULL)
4773 return -ENOMEM;
4774
4775 codec->spec = spec;
4776
f5fcc13c
TI
4777 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4778 alc880_models,
4779 alc880_cfg_tbl);
4780 if (board_config < 0) {
9a11f1aa
TI
4781 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4782 codec->chip_name);
e9edcee0 4783 board_config = ALC880_AUTO;
1da177e4 4784 }
1da177e4 4785
e9edcee0
TI
4786 if (board_config == ALC880_AUTO) {
4787 /* automatic parse from the BIOS config */
4788 err = alc880_parse_auto_config(codec);
4789 if (err < 0) {
4790 alc_free(codec);
4791 return err;
f12ab1e0 4792 } else if (!err) {
9c7f852e
TI
4793 printk(KERN_INFO
4794 "hda_codec: Cannot set up configuration "
4795 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
4796 board_config = ALC880_3ST;
4797 }
1da177e4
LT
4798 }
4799
680cd536
KK
4800 err = snd_hda_attach_beep_device(codec, 0x1);
4801 if (err < 0) {
4802 alc_free(codec);
4803 return err;
4804 }
4805
df694daa 4806 if (board_config != ALC880_AUTO)
e9c364c0 4807 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 4808
1da177e4
LT
4809 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4810 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 4811 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 4812
1da177e4
LT
4813 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4814 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4815
f12ab1e0 4816 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 4817 /* check whether NID 0x07 is valid */
54d17403 4818 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 4819 /* get type */
a22d543a 4820 wcap = get_wcaps_type(wcap);
e9edcee0
TI
4821 if (wcap != AC_WID_AUD_IN) {
4822 spec->adc_nids = alc880_adc_nids_alt;
4823 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
4824 } else {
4825 spec->adc_nids = alc880_adc_nids;
4826 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
4827 }
4828 }
b59bdf3b 4829 set_capture_mixer(codec);
45bdd1c1 4830 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 4831
2134ea4f
TI
4832 spec->vmaster_nid = 0x0c;
4833
1da177e4 4834 codec->patch_ops = alc_patch_ops;
e9edcee0 4835 if (board_config == ALC880_AUTO)
ae6b813a 4836 spec->init_hook = alc880_auto_init;
cb53c626
TI
4837#ifdef CONFIG_SND_HDA_POWER_SAVE
4838 if (!spec->loopback.amplist)
4839 spec->loopback.amplist = alc880_loopbacks;
4840#endif
daead538 4841 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
4842
4843 return 0;
4844}
4845
e9edcee0 4846
1da177e4
LT
4847/*
4848 * ALC260 support
4849 */
4850
e9edcee0
TI
4851static hda_nid_t alc260_dac_nids[1] = {
4852 /* front */
4853 0x02,
4854};
4855
4856static hda_nid_t alc260_adc_nids[1] = {
4857 /* ADC0 */
4858 0x04,
4859};
4860
df694daa 4861static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4862 /* ADC1 */
4863 0x05,
4864};
4865
d57fdac0
JW
4866/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4867 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4868 */
4869static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4870 /* ADC0, ADC1 */
4871 0x04, 0x05
4872};
4873
e9edcee0
TI
4874#define ALC260_DIGOUT_NID 0x03
4875#define ALC260_DIGIN_NID 0x06
4876
4877static struct hda_input_mux alc260_capture_source = {
4878 .num_items = 4,
4879 .items = {
4880 { "Mic", 0x0 },
4881 { "Front Mic", 0x1 },
4882 { "Line", 0x2 },
4883 { "CD", 0x4 },
4884 },
4885};
4886
17e7aec6 4887/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4888 * headphone jack and the internal CD lines since these are the only pins at
4889 * which audio can appear. For flexibility, also allow the option of
4890 * recording the mixer output on the second ADC (ADC0 doesn't have a
4891 * connection to the mixer output).
a9430dd8 4892 */
a1e8d2da
JW
4893static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4894 {
4895 .num_items = 3,
4896 .items = {
4897 { "Mic/Line", 0x0 },
4898 { "CD", 0x4 },
4899 { "Headphone", 0x2 },
4900 },
a9430dd8 4901 },
a1e8d2da
JW
4902 {
4903 .num_items = 4,
4904 .items = {
4905 { "Mic/Line", 0x0 },
4906 { "CD", 0x4 },
4907 { "Headphone", 0x2 },
4908 { "Mixer", 0x5 },
4909 },
4910 },
4911
a9430dd8
JW
4912};
4913
a1e8d2da
JW
4914/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4915 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4916 */
a1e8d2da
JW
4917static struct hda_input_mux alc260_acer_capture_sources[2] = {
4918 {
4919 .num_items = 4,
4920 .items = {
4921 { "Mic", 0x0 },
4922 { "Line", 0x2 },
4923 { "CD", 0x4 },
4924 { "Headphone", 0x5 },
4925 },
4926 },
4927 {
4928 .num_items = 5,
4929 .items = {
4930 { "Mic", 0x0 },
4931 { "Line", 0x2 },
4932 { "CD", 0x4 },
4933 { "Headphone", 0x6 },
4934 { "Mixer", 0x5 },
4935 },
0bfc90e9
JW
4936 },
4937};
cc959489
MS
4938
4939/* Maxdata Favorit 100XS */
4940static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4941 {
4942 .num_items = 2,
4943 .items = {
4944 { "Line/Mic", 0x0 },
4945 { "CD", 0x4 },
4946 },
4947 },
4948 {
4949 .num_items = 3,
4950 .items = {
4951 { "Line/Mic", 0x0 },
4952 { "CD", 0x4 },
4953 { "Mixer", 0x5 },
4954 },
4955 },
4956};
4957
1da177e4
LT
4958/*
4959 * This is just place-holder, so there's something for alc_build_pcms to look
4960 * at when it calculates the maximum number of channels. ALC260 has no mixer
4961 * element which allows changing the channel mode, so the verb list is
4962 * never used.
4963 */
d2a6d7dc 4964static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4965 { 2, NULL },
4966};
4967
df694daa
KY
4968
4969/* Mixer combinations
4970 *
4971 * basic: base_output + input + pc_beep + capture
4972 * HP: base_output + input + capture_alt
4973 * HP_3013: hp_3013 + input + capture
4974 * fujitsu: fujitsu + capture
0bfc90e9 4975 * acer: acer + capture
df694daa
KY
4976 */
4977
4978static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4979 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4980 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4981 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4982 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4983 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4984 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4985 { } /* end */
f12ab1e0 4986};
1da177e4 4987
df694daa 4988static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4989 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4990 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4991 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4992 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4994 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4996 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4997 { } /* end */
4998};
4999
bec15c3a
TI
5000/* update HP, line and mono out pins according to the master switch */
5001static void alc260_hp_master_update(struct hda_codec *codec,
5002 hda_nid_t hp, hda_nid_t line,
5003 hda_nid_t mono)
5004{
5005 struct alc_spec *spec = codec->spec;
5006 unsigned int val = spec->master_sw ? PIN_HP : 0;
5007 /* change HP and line-out pins */
30cde0aa 5008 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5009 val);
30cde0aa 5010 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5011 val);
5012 /* mono (speaker) depending on the HP jack sense */
5013 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5014 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5015 val);
5016}
5017
5018static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5019 struct snd_ctl_elem_value *ucontrol)
5020{
5021 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5022 struct alc_spec *spec = codec->spec;
5023 *ucontrol->value.integer.value = spec->master_sw;
5024 return 0;
5025}
5026
5027static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5028 struct snd_ctl_elem_value *ucontrol)
5029{
5030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5031 struct alc_spec *spec = codec->spec;
5032 int val = !!*ucontrol->value.integer.value;
5033 hda_nid_t hp, line, mono;
5034
5035 if (val == spec->master_sw)
5036 return 0;
5037 spec->master_sw = val;
5038 hp = (kcontrol->private_value >> 16) & 0xff;
5039 line = (kcontrol->private_value >> 8) & 0xff;
5040 mono = kcontrol->private_value & 0xff;
5041 alc260_hp_master_update(codec, hp, line, mono);
5042 return 1;
5043}
5044
5045static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5046 {
5047 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5048 .name = "Master Playback Switch",
5049 .info = snd_ctl_boolean_mono_info,
5050 .get = alc260_hp_master_sw_get,
5051 .put = alc260_hp_master_sw_put,
5052 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5053 },
5054 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5055 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5056 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5057 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5058 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5059 HDA_OUTPUT),
5060 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5061 { } /* end */
5062};
5063
5064static struct hda_verb alc260_hp_unsol_verbs[] = {
5065 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5066 {},
5067};
5068
5069static void alc260_hp_automute(struct hda_codec *codec)
5070{
5071 struct alc_spec *spec = codec->spec;
5072 unsigned int present;
5073
5074 present = snd_hda_codec_read(codec, 0x10, 0,
5075 AC_VERB_GET_PIN_SENSE, 0);
5076 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5077 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5078}
5079
5080static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5081{
5082 if ((res >> 26) == ALC880_HP_EVENT)
5083 alc260_hp_automute(codec);
5084}
5085
df694daa 5086static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5087 {
5088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5089 .name = "Master Playback Switch",
5090 .info = snd_ctl_boolean_mono_info,
5091 .get = alc260_hp_master_sw_get,
5092 .put = alc260_hp_master_sw_put,
30cde0aa 5093 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5094 },
df694daa
KY
5095 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5096 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5097 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5098 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5099 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5100 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5101 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5102 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5103 { } /* end */
5104};
5105
3f878308
KY
5106static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5107 .ops = &snd_hda_bind_vol,
5108 .values = {
5109 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5110 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5111 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5112 0
5113 },
5114};
5115
5116static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5117 .ops = &snd_hda_bind_sw,
5118 .values = {
5119 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5120 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5121 0
5122 },
5123};
5124
5125static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5126 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5127 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5128 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5129 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5130 { } /* end */
5131};
5132
bec15c3a
TI
5133static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5134 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5135 {},
5136};
5137
5138static void alc260_hp_3013_automute(struct hda_codec *codec)
5139{
5140 struct alc_spec *spec = codec->spec;
5141 unsigned int present;
5142
5143 present = snd_hda_codec_read(codec, 0x15, 0,
5144 AC_VERB_GET_PIN_SENSE, 0);
5145 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
30cde0aa 5146 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5147}
5148
5149static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5150 unsigned int res)
5151{
5152 if ((res >> 26) == ALC880_HP_EVENT)
5153 alc260_hp_3013_automute(codec);
5154}
5155
3f878308
KY
5156static void alc260_hp_3012_automute(struct hda_codec *codec)
5157{
5158 unsigned int present, bits;
5159
5160 present = snd_hda_codec_read(codec, 0x10, 0,
5161 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
5162
5163 bits = present ? 0 : PIN_OUT;
5164 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5165 bits);
5166 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5167 bits);
5168 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5169 bits);
5170}
5171
5172static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5173 unsigned int res)
5174{
5175 if ((res >> 26) == ALC880_HP_EVENT)
5176 alc260_hp_3012_automute(codec);
5177}
5178
5179/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5180 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5181 */
c8b6bf9b 5182static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5183 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5184 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5185 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5186 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5187 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5188 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5189 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5190 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5192 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5193 { } /* end */
5194};
5195
a1e8d2da
JW
5196/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5197 * versions of the ALC260 don't act on requests to enable mic bias from NID
5198 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5199 * datasheet doesn't mention this restriction. At this stage it's not clear
5200 * whether this behaviour is intentional or is a hardware bug in chip
5201 * revisions available in early 2006. Therefore for now allow the
5202 * "Headphone Jack Mode" control to span all choices, but if it turns out
5203 * that the lack of mic bias for this NID is intentional we could change the
5204 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5205 *
5206 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5207 * don't appear to make the mic bias available from the "line" jack, even
5208 * though the NID used for this jack (0x14) can supply it. The theory is
5209 * that perhaps Acer have included blocking capacitors between the ALC260
5210 * and the output jack. If this turns out to be the case for all such
5211 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5212 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5213 *
5214 * The C20x Tablet series have a mono internal speaker which is controlled
5215 * via the chip's Mono sum widget and pin complex, so include the necessary
5216 * controls for such models. On models without a "mono speaker" the control
5217 * won't do anything.
a1e8d2da 5218 */
0bfc90e9
JW
5219static struct snd_kcontrol_new alc260_acer_mixer[] = {
5220 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5221 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5222 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5223 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5224 HDA_OUTPUT),
31bffaa9 5225 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5226 HDA_INPUT),
0bfc90e9
JW
5227 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5228 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5230 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5231 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5232 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5233 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5234 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5235 { } /* end */
5236};
5237
cc959489
MS
5238/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5239 */
5240static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5241 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5242 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5243 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5244 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5245 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5246 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5247 { } /* end */
5248};
5249
bc9f98a9
KY
5250/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5251 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5252 */
5253static struct snd_kcontrol_new alc260_will_mixer[] = {
5254 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5255 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5257 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5258 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5259 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5260 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5261 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5262 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5263 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5264 { } /* end */
5265};
5266
5267/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5268 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5269 */
5270static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5271 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5272 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5273 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5274 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5275 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5276 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5277 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5278 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5279 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5280 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5281 { } /* end */
5282};
5283
df694daa
KY
5284/*
5285 * initialization verbs
5286 */
1da177e4
LT
5287static struct hda_verb alc260_init_verbs[] = {
5288 /* Line In pin widget for input */
05acb863 5289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5290 /* CD pin widget for input */
05acb863 5291 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5292 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5293 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5294 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5295 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5296 /* LINE-2 is used for line-out in rear */
05acb863 5297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5298 /* select line-out */
fd56f2db 5299 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5300 /* LINE-OUT pin */
05acb863 5301 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5302 /* enable HP */
05acb863 5303 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5304 /* enable Mono */
05acb863
TI
5305 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5306 /* mute capture amp left and right */
16ded525 5307 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5308 /* set connection select to line in (default select for this ADC) */
5309 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5310 /* mute capture amp left and right */
5311 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5312 /* set connection select to line in (default select for this ADC) */
5313 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5314 /* set vol=0 Line-Out mixer amp left and right */
5315 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5316 /* unmute pin widget amp left and right (no gain on this amp) */
5317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5318 /* set vol=0 HP mixer amp left and right */
5319 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5320 /* unmute pin widget amp left and right (no gain on this amp) */
5321 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5322 /* set vol=0 Mono mixer amp left and right */
5323 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5324 /* unmute pin widget amp left and right (no gain on this amp) */
5325 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5326 /* unmute LINE-2 out pin */
5327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5328 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5329 * Line In 2 = 0x03
5330 */
cb53c626
TI
5331 /* mute analog inputs */
5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5337 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5338 /* mute Front out path */
5339 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5340 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5341 /* mute Headphone out path */
5342 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5343 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5344 /* mute Mono out path */
5345 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5346 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5347 { }
5348};
5349
474167d6 5350#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5351static struct hda_verb alc260_hp_init_verbs[] = {
5352 /* Headphone and output */
5353 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5354 /* mono output */
5355 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5356 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5357 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5358 /* Mic2 (front panel) pin widget for input and vref at 80% */
5359 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5360 /* Line In pin widget for input */
5361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5362 /* Line-2 pin widget for output */
5363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5364 /* CD pin widget for input */
5365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5366 /* unmute amp left and right */
5367 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5368 /* set connection select to line in (default select for this ADC) */
5369 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5370 /* unmute Line-Out mixer amp left and right (volume = 0) */
5371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5372 /* mute pin widget amp left and right (no gain on this amp) */
5373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5374 /* unmute HP mixer amp left and right (volume = 0) */
5375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5376 /* mute pin widget amp left and right (no gain on this amp) */
5377 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5378 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5379 * Line In 2 = 0x03
5380 */
cb53c626
TI
5381 /* mute analog inputs */
5382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5383 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5386 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5387 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5388 /* Unmute Front out path */
5389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5391 /* Unmute Headphone out path */
5392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5394 /* Unmute Mono out path */
5395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5396 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5397 { }
5398};
474167d6 5399#endif
df694daa
KY
5400
5401static struct hda_verb alc260_hp_3013_init_verbs[] = {
5402 /* Line out and output */
5403 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5404 /* mono output */
5405 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5406 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5407 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5408 /* Mic2 (front panel) pin widget for input and vref at 80% */
5409 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5410 /* Line In pin widget for input */
5411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5412 /* Headphone pin widget for output */
5413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5414 /* CD pin widget for input */
5415 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5416 /* unmute amp left and right */
5417 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5418 /* set connection select to line in (default select for this ADC) */
5419 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5420 /* unmute Line-Out mixer amp left and right (volume = 0) */
5421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5422 /* mute pin widget amp left and right (no gain on this amp) */
5423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5424 /* unmute HP mixer amp left and right (volume = 0) */
5425 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5426 /* mute pin widget amp left and right (no gain on this amp) */
5427 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5428 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5429 * Line In 2 = 0x03
5430 */
cb53c626
TI
5431 /* mute analog inputs */
5432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5434 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5435 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5437 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5438 /* Unmute Front out path */
5439 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5441 /* Unmute Headphone out path */
5442 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5444 /* Unmute Mono out path */
5445 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5446 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5447 { }
5448};
5449
a9430dd8 5450/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5451 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5452 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5453 */
5454static struct hda_verb alc260_fujitsu_init_verbs[] = {
5455 /* Disable all GPIOs */
5456 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5457 /* Internal speaker is connected to headphone pin */
5458 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5459 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5461 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5462 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5463 /* Ensure all other unused pins are disabled and muted. */
5464 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5466 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5467 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5468 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5469 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5472
5473 /* Disable digital (SPDIF) pins */
5474 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5475 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5476
ea1fb29a 5477 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5478 * when acting as an output.
5479 */
5480 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5481
f7ace40d 5482 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5483 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5489 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5492
f7ace40d
JW
5493 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5494 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5495 /* Unmute Line1 pin widget output buffer since it starts as an output.
5496 * If the pin mode is changed by the user the pin mode control will
5497 * take care of enabling the pin's input/output buffers as needed.
5498 * Therefore there's no need to enable the input buffer at this
5499 * stage.
cdcd9268 5500 */
f7ace40d 5501 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5502 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5503 * mixer ctrl)
5504 */
f7ace40d
JW
5505 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5506
5507 /* Mute capture amp left and right */
5508 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5509 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5510 * in (on mic1 pin)
5511 */
5512 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5513
5514 /* Do the same for the second ADC: mute capture input amp and
5515 * set ADC connection to line in (on mic1 pin)
5516 */
5517 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5518 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5519
5520 /* Mute all inputs to mixer widget (even unconnected ones) */
5521 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5529
5530 { }
a9430dd8
JW
5531};
5532
0bfc90e9
JW
5533/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5534 * similar laptops (adapted from Fujitsu init verbs).
5535 */
5536static struct hda_verb alc260_acer_init_verbs[] = {
5537 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5538 * the headphone jack. Turn this on and rely on the standard mute
5539 * methods whenever the user wants to turn these outputs off.
5540 */
5541 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5542 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5543 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5544 /* Internal speaker/Headphone jack is connected to Line-out pin */
5545 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5546 /* Internal microphone/Mic jack is connected to Mic1 pin */
5547 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5548 /* Line In jack is connected to Line1 pin */
5549 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5550 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5551 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5552 /* Ensure all other unused pins are disabled and muted. */
5553 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5554 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5555 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5556 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5559 /* Disable digital (SPDIF) pins */
5560 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5561 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5562
ea1fb29a 5563 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5564 * bus when acting as outputs.
5565 */
5566 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5567 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5568
5569 /* Start with output sum widgets muted and their output gains at min */
5570 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5571 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5574 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5575 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5576 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5577 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5578 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5579
f12ab1e0
TI
5580 /* Unmute Line-out pin widget amp left and right
5581 * (no equiv mixer ctrl)
5582 */
0bfc90e9 5583 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5584 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5585 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5586 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5587 * inputs. If the pin mode is changed by the user the pin mode control
5588 * will take care of enabling the pin's input/output buffers as needed.
5589 * Therefore there's no need to enable the input buffer at this
5590 * stage.
5591 */
5592 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5593 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5594
5595 /* Mute capture amp left and right */
5596 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5597 /* Set ADC connection select to match default mixer setting - mic
5598 * (on mic1 pin)
5599 */
5600 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5601
5602 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5603 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5604 */
5605 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5606 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5607
5608 /* Mute all inputs to mixer widget (even unconnected ones) */
5609 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5610 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5612 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5617
5618 { }
5619};
5620
cc959489
MS
5621/* Initialisation sequence for Maxdata Favorit 100XS
5622 * (adapted from Acer init verbs).
5623 */
5624static struct hda_verb alc260_favorit100_init_verbs[] = {
5625 /* GPIO 0 enables the output jack.
5626 * Turn this on and rely on the standard mute
5627 * methods whenever the user wants to turn these outputs off.
5628 */
5629 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5630 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5631 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5632 /* Line/Mic input jack is connected to Mic1 pin */
5633 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5634 /* Ensure all other unused pins are disabled and muted. */
5635 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5636 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5637 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5638 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5639 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5640 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5641 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5642 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5645 /* Disable digital (SPDIF) pins */
5646 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5647 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5648
5649 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5650 * bus when acting as outputs.
5651 */
5652 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5653 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5654
5655 /* Start with output sum widgets muted and their output gains at min */
5656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5657 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5658 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5660 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5661 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5663 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5664 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5665
5666 /* Unmute Line-out pin widget amp left and right
5667 * (no equiv mixer ctrl)
5668 */
5669 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5670 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5671 * inputs. If the pin mode is changed by the user the pin mode control
5672 * will take care of enabling the pin's input/output buffers as needed.
5673 * Therefore there's no need to enable the input buffer at this
5674 * stage.
5675 */
5676 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5677
5678 /* Mute capture amp left and right */
5679 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5680 /* Set ADC connection select to match default mixer setting - mic
5681 * (on mic1 pin)
5682 */
5683 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5684
5685 /* Do similar with the second ADC: mute capture input amp and
5686 * set ADC connection to mic to match ALSA's default state.
5687 */
5688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5689 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5690
5691 /* Mute all inputs to mixer widget (even unconnected ones) */
5692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5696 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5697 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5700
5701 { }
5702};
5703
bc9f98a9
KY
5704static struct hda_verb alc260_will_verbs[] = {
5705 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5706 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5707 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5708 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5709 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5710 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5711 {}
5712};
5713
5714static struct hda_verb alc260_replacer_672v_verbs[] = {
5715 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5716 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5717 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5718
5719 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5720 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5721 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5722
5723 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5724 {}
5725};
5726
5727/* toggle speaker-output according to the hp-jack state */
5728static void alc260_replacer_672v_automute(struct hda_codec *codec)
5729{
5730 unsigned int present;
5731
5732 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5733 present = snd_hda_codec_read(codec, 0x0f, 0,
5734 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5735 if (present) {
82beb8fd
TI
5736 snd_hda_codec_write_cache(codec, 0x01, 0,
5737 AC_VERB_SET_GPIO_DATA, 1);
5738 snd_hda_codec_write_cache(codec, 0x0f, 0,
5739 AC_VERB_SET_PIN_WIDGET_CONTROL,
5740 PIN_HP);
bc9f98a9 5741 } else {
82beb8fd
TI
5742 snd_hda_codec_write_cache(codec, 0x01, 0,
5743 AC_VERB_SET_GPIO_DATA, 0);
5744 snd_hda_codec_write_cache(codec, 0x0f, 0,
5745 AC_VERB_SET_PIN_WIDGET_CONTROL,
5746 PIN_OUT);
bc9f98a9
KY
5747 }
5748}
5749
5750static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5751 unsigned int res)
5752{
5753 if ((res >> 26) == ALC880_HP_EVENT)
5754 alc260_replacer_672v_automute(codec);
5755}
5756
3f878308
KY
5757static struct hda_verb alc260_hp_dc7600_verbs[] = {
5758 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5760 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5761 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5762 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5763 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5764 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5765 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5766 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5768 {}
5769};
5770
7cf51e48
JW
5771/* Test configuration for debugging, modelled after the ALC880 test
5772 * configuration.
5773 */
5774#ifdef CONFIG_SND_DEBUG
5775static hda_nid_t alc260_test_dac_nids[1] = {
5776 0x02,
5777};
5778static hda_nid_t alc260_test_adc_nids[2] = {
5779 0x04, 0x05,
5780};
a1e8d2da 5781/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 5782 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 5783 * is NID 0x04.
17e7aec6 5784 */
a1e8d2da
JW
5785static struct hda_input_mux alc260_test_capture_sources[2] = {
5786 {
5787 .num_items = 7,
5788 .items = {
5789 { "MIC1 pin", 0x0 },
5790 { "MIC2 pin", 0x1 },
5791 { "LINE1 pin", 0x2 },
5792 { "LINE2 pin", 0x3 },
5793 { "CD pin", 0x4 },
5794 { "LINE-OUT pin", 0x5 },
5795 { "HP-OUT pin", 0x6 },
5796 },
5797 },
5798 {
5799 .num_items = 8,
5800 .items = {
5801 { "MIC1 pin", 0x0 },
5802 { "MIC2 pin", 0x1 },
5803 { "LINE1 pin", 0x2 },
5804 { "LINE2 pin", 0x3 },
5805 { "CD pin", 0x4 },
5806 { "Mixer", 0x5 },
5807 { "LINE-OUT pin", 0x6 },
5808 { "HP-OUT pin", 0x7 },
5809 },
7cf51e48
JW
5810 },
5811};
5812static struct snd_kcontrol_new alc260_test_mixer[] = {
5813 /* Output driver widgets */
5814 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5815 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5816 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5817 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5818 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5819 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5820
a1e8d2da
JW
5821 /* Modes for retasking pin widgets
5822 * Note: the ALC260 doesn't seem to act on requests to enable mic
5823 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5824 * mention this restriction. At this stage it's not clear whether
5825 * this behaviour is intentional or is a hardware bug in chip
5826 * revisions available at least up until early 2006. Therefore for
5827 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5828 * choices, but if it turns out that the lack of mic bias for these
5829 * NIDs is intentional we could change their modes from
5830 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5831 */
7cf51e48
JW
5832 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5833 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5834 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5835 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5836 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5837 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5838
5839 /* Loopback mixer controls */
5840 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5841 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5842 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5843 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5844 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5845 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5846 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5847 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5848 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5849 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
5850 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5851 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5852 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5853 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
5854
5855 /* Controls for GPIO pins, assuming they are configured as outputs */
5856 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5857 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5858 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5859 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5860
92621f13
JW
5861 /* Switches to allow the digital IO pins to be enabled. The datasheet
5862 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 5863 * make this output available should provide clarification.
92621f13
JW
5864 */
5865 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5866 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5867
f8225f6d
JW
5868 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5869 * this output to turn on an external amplifier.
5870 */
5871 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5872 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5873
7cf51e48
JW
5874 { } /* end */
5875};
5876static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
5877 /* Enable all GPIOs as outputs with an initial value of 0 */
5878 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5879 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5880 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5881
7cf51e48
JW
5882 /* Enable retasking pins as output, initially without power amp */
5883 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5884 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5885 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5887 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5888 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5889
92621f13
JW
5890 /* Disable digital (SPDIF) pins initially, but users can enable
5891 * them via a mixer switch. In the case of SPDIF-out, this initverb
5892 * payload also sets the generation to 0, output to be in "consumer"
5893 * PCM format, copyright asserted, no pre-emphasis and no validity
5894 * control.
5895 */
7cf51e48
JW
5896 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5897 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5898
ea1fb29a 5899 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5900 * OUT1 sum bus when acting as an output.
5901 */
5902 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5903 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5904 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5905 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5906
5907 /* Start with output sum widgets muted and their output gains at min */
5908 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5909 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5910 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5911 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5912 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5913 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5914 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5915 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5916 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5917
cdcd9268
JW
5918 /* Unmute retasking pin widget output buffers since the default
5919 * state appears to be output. As the pin mode is changed by the
5920 * user the pin mode control will take care of enabling the pin's
5921 * input/output buffers as needed.
5922 */
7cf51e48
JW
5923 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5924 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5925 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5927 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5928 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5929 /* Also unmute the mono-out pin widget */
5930 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5931
7cf51e48
JW
5932 /* Mute capture amp left and right */
5933 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5934 /* Set ADC connection select to match default mixer setting (mic1
5935 * pin)
7cf51e48
JW
5936 */
5937 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5938
5939 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5940 * set ADC connection to mic1 pin
7cf51e48
JW
5941 */
5942 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5943 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5944
5945 /* Mute all inputs to mixer widget (even unconnected ones) */
5946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5950 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5952 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5954
5955 { }
5956};
5957#endif
5958
6330079f
TI
5959#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5960#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5961
a3bcba38
TI
5962#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5963#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5964
df694daa
KY
5965/*
5966 * for BIOS auto-configuration
5967 */
16ded525 5968
df694daa 5969static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5970 const char *pfx, int *vol_bits)
df694daa
KY
5971{
5972 hda_nid_t nid_vol;
5973 unsigned long vol_val, sw_val;
5974 char name[32];
5975 int err;
5976
5977 if (nid >= 0x0f && nid < 0x11) {
5978 nid_vol = nid - 0x7;
5979 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5980 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5981 } else if (nid == 0x11) {
5982 nid_vol = nid - 0x7;
5983 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5984 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5985 } else if (nid >= 0x12 && nid <= 0x15) {
5986 nid_vol = 0x08;
5987 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5988 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5989 } else
5990 return 0; /* N/A */
ea1fb29a 5991
863b4518
TI
5992 if (!(*vol_bits & (1 << nid_vol))) {
5993 /* first control for the volume widget */
5994 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5995 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5996 if (err < 0)
5997 return err;
5998 *vol_bits |= (1 << nid_vol);
5999 }
df694daa 6000 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
6001 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
6002 if (err < 0)
df694daa
KY
6003 return err;
6004 return 1;
6005}
6006
6007/* add playback controls from the parsed DAC table */
6008static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6009 const struct auto_pin_cfg *cfg)
6010{
6011 hda_nid_t nid;
6012 int err;
863b4518 6013 int vols = 0;
df694daa
KY
6014
6015 spec->multiout.num_dacs = 1;
6016 spec->multiout.dac_nids = spec->private_dac_nids;
6017 spec->multiout.dac_nids[0] = 0x02;
6018
6019 nid = cfg->line_out_pins[0];
6020 if (nid) {
23112d6d
TI
6021 const char *pfx;
6022 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6023 pfx = "Master";
6024 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6025 pfx = "Speaker";
6026 else
6027 pfx = "Front";
6028 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6029 if (err < 0)
6030 return err;
6031 }
6032
82bc955f 6033 nid = cfg->speaker_pins[0];
df694daa 6034 if (nid) {
863b4518 6035 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6036 if (err < 0)
6037 return err;
6038 }
6039
eb06ed8f 6040 nid = cfg->hp_pins[0];
df694daa 6041 if (nid) {
863b4518
TI
6042 err = alc260_add_playback_controls(spec, nid, "Headphone",
6043 &vols);
df694daa
KY
6044 if (err < 0)
6045 return err;
6046 }
f12ab1e0 6047 return 0;
df694daa
KY
6048}
6049
6050/* create playback/capture controls for input pins */
05f5f477 6051static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6052 const struct auto_pin_cfg *cfg)
6053{
05f5f477 6054 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6055}
6056
6057static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6058 hda_nid_t nid, int pin_type,
6059 int sel_idx)
6060{
f6c7e546 6061 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6062 /* need the manual connection? */
6063 if (nid >= 0x12) {
6064 int idx = nid - 0x12;
6065 snd_hda_codec_write(codec, idx + 0x0b, 0,
6066 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6067 }
6068}
6069
6070static void alc260_auto_init_multi_out(struct hda_codec *codec)
6071{
6072 struct alc_spec *spec = codec->spec;
6073 hda_nid_t nid;
6074
f12ab1e0 6075 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6076 if (nid) {
6077 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6078 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6079 }
ea1fb29a 6080
82bc955f 6081 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6082 if (nid)
6083 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6084
eb06ed8f 6085 nid = spec->autocfg.hp_pins[0];
df694daa 6086 if (nid)
baba8ee9 6087 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6088}
df694daa
KY
6089
6090#define ALC260_PIN_CD_NID 0x16
6091static void alc260_auto_init_analog_input(struct hda_codec *codec)
6092{
6093 struct alc_spec *spec = codec->spec;
6094 int i;
6095
6096 for (i = 0; i < AUTO_PIN_LAST; i++) {
6097 hda_nid_t nid = spec->autocfg.input_pins[i];
6098 if (nid >= 0x12) {
23f0c048 6099 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6100 if (nid != ALC260_PIN_CD_NID &&
6101 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6102 snd_hda_codec_write(codec, nid, 0,
6103 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6104 AMP_OUT_MUTE);
6105 }
6106 }
6107}
6108
6109/*
6110 * generic initialization of ADC, input mixers and output mixers
6111 */
6112static struct hda_verb alc260_volume_init_verbs[] = {
6113 /*
6114 * Unmute ADC0-1 and set the default input to mic-in
6115 */
6116 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6117 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6118 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6119 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6120
df694daa
KY
6121 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6122 * mixer widget
f12ab1e0
TI
6123 * Note: PASD motherboards uses the Line In 2 as the input for
6124 * front panel mic (mic 2)
df694daa
KY
6125 */
6126 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6127 /* mute analog inputs */
6128 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6133
6134 /*
6135 * Set up output mixers (0x08 - 0x0a)
6136 */
6137 /* set vol=0 to output mixers */
6138 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6139 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6140 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6141 /* set up input amps for analog loopback */
6142 /* Amp Indices: DAC = 0, mixer = 1 */
6143 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6145 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6146 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6147 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6148 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6149
df694daa
KY
6150 { }
6151};
6152
6153static int alc260_parse_auto_config(struct hda_codec *codec)
6154{
6155 struct alc_spec *spec = codec->spec;
df694daa
KY
6156 int err;
6157 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6158
f12ab1e0
TI
6159 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6160 alc260_ignore);
6161 if (err < 0)
df694daa 6162 return err;
f12ab1e0
TI
6163 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6164 if (err < 0)
4a471b7d 6165 return err;
603c4019 6166 if (!spec->kctls.list)
df694daa 6167 return 0; /* can't find valid BIOS pin config */
05f5f477 6168 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6169 if (err < 0)
df694daa
KY
6170 return err;
6171
6172 spec->multiout.max_channels = 2;
6173
0852d7a6 6174 if (spec->autocfg.dig_outs)
df694daa 6175 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6176 if (spec->kctls.list)
d88897ea 6177 add_mixer(spec, spec->kctls.list);
df694daa 6178
d88897ea 6179 add_verb(spec, alc260_volume_init_verbs);
df694daa 6180
a1e8d2da 6181 spec->num_mux_defs = 1;
61b9b9b1 6182 spec->input_mux = &spec->private_imux[0];
df694daa 6183
4a79ba34
TI
6184 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6185
df694daa
KY
6186 return 1;
6187}
6188
ae6b813a
TI
6189/* additional initialization for auto-configuration model */
6190static void alc260_auto_init(struct hda_codec *codec)
df694daa 6191{
f6c7e546 6192 struct alc_spec *spec = codec->spec;
df694daa
KY
6193 alc260_auto_init_multi_out(codec);
6194 alc260_auto_init_analog_input(codec);
f6c7e546 6195 if (spec->unsol_event)
7fb0d78f 6196 alc_inithook(codec);
df694daa
KY
6197}
6198
cb53c626
TI
6199#ifdef CONFIG_SND_HDA_POWER_SAVE
6200static struct hda_amp_list alc260_loopbacks[] = {
6201 { 0x07, HDA_INPUT, 0 },
6202 { 0x07, HDA_INPUT, 1 },
6203 { 0x07, HDA_INPUT, 2 },
6204 { 0x07, HDA_INPUT, 3 },
6205 { 0x07, HDA_INPUT, 4 },
6206 { } /* end */
6207};
6208#endif
6209
df694daa
KY
6210/*
6211 * ALC260 configurations
6212 */
f5fcc13c
TI
6213static const char *alc260_models[ALC260_MODEL_LAST] = {
6214 [ALC260_BASIC] = "basic",
6215 [ALC260_HP] = "hp",
6216 [ALC260_HP_3013] = "hp-3013",
2922c9af 6217 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6218 [ALC260_FUJITSU_S702X] = "fujitsu",
6219 [ALC260_ACER] = "acer",
bc9f98a9
KY
6220 [ALC260_WILL] = "will",
6221 [ALC260_REPLACER_672V] = "replacer",
cc959489 6222 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6223#ifdef CONFIG_SND_DEBUG
f5fcc13c 6224 [ALC260_TEST] = "test",
7cf51e48 6225#endif
f5fcc13c
TI
6226 [ALC260_AUTO] = "auto",
6227};
6228
6229static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6230 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 6231 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6232 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6233 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 6234 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 6235 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6236 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6237 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6238 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6239 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6240 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6241 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6242 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6243 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6244 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6245 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6246 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6247 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6248 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6249 {}
6250};
6251
6252static struct alc_config_preset alc260_presets[] = {
6253 [ALC260_BASIC] = {
6254 .mixers = { alc260_base_output_mixer,
45bdd1c1 6255 alc260_input_mixer },
df694daa
KY
6256 .init_verbs = { alc260_init_verbs },
6257 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6258 .dac_nids = alc260_dac_nids,
f9e336f6 6259 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
6260 .adc_nids = alc260_adc_nids,
6261 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6262 .channel_mode = alc260_modes,
6263 .input_mux = &alc260_capture_source,
6264 },
6265 [ALC260_HP] = {
bec15c3a 6266 .mixers = { alc260_hp_output_mixer,
f9e336f6 6267 alc260_input_mixer },
bec15c3a
TI
6268 .init_verbs = { alc260_init_verbs,
6269 alc260_hp_unsol_verbs },
df694daa
KY
6270 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6271 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6272 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6273 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6274 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6275 .channel_mode = alc260_modes,
6276 .input_mux = &alc260_capture_source,
bec15c3a
TI
6277 .unsol_event = alc260_hp_unsol_event,
6278 .init_hook = alc260_hp_automute,
df694daa 6279 },
3f878308
KY
6280 [ALC260_HP_DC7600] = {
6281 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6282 alc260_input_mixer },
3f878308
KY
6283 .init_verbs = { alc260_init_verbs,
6284 alc260_hp_dc7600_verbs },
6285 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6286 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6287 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6288 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6289 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6290 .channel_mode = alc260_modes,
6291 .input_mux = &alc260_capture_source,
6292 .unsol_event = alc260_hp_3012_unsol_event,
6293 .init_hook = alc260_hp_3012_automute,
6294 },
df694daa
KY
6295 [ALC260_HP_3013] = {
6296 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6297 alc260_input_mixer },
bec15c3a
TI
6298 .init_verbs = { alc260_hp_3013_init_verbs,
6299 alc260_hp_3013_unsol_verbs },
df694daa
KY
6300 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6301 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6302 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6303 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6304 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6305 .channel_mode = alc260_modes,
6306 .input_mux = &alc260_capture_source,
bec15c3a
TI
6307 .unsol_event = alc260_hp_3013_unsol_event,
6308 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6309 },
6310 [ALC260_FUJITSU_S702X] = {
f9e336f6 6311 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6312 .init_verbs = { alc260_fujitsu_init_verbs },
6313 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6314 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6315 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6316 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6317 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6318 .channel_mode = alc260_modes,
a1e8d2da
JW
6319 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6320 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6321 },
0bfc90e9 6322 [ALC260_ACER] = {
f9e336f6 6323 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6324 .init_verbs = { alc260_acer_init_verbs },
6325 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6326 .dac_nids = alc260_dac_nids,
6327 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6328 .adc_nids = alc260_dual_adc_nids,
6329 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6330 .channel_mode = alc260_modes,
a1e8d2da
JW
6331 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6332 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6333 },
cc959489
MS
6334 [ALC260_FAVORIT100] = {
6335 .mixers = { alc260_favorit100_mixer },
6336 .init_verbs = { alc260_favorit100_init_verbs },
6337 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6338 .dac_nids = alc260_dac_nids,
6339 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6340 .adc_nids = alc260_dual_adc_nids,
6341 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6342 .channel_mode = alc260_modes,
6343 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6344 .input_mux = alc260_favorit100_capture_sources,
6345 },
bc9f98a9 6346 [ALC260_WILL] = {
f9e336f6 6347 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6348 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6349 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6350 .dac_nids = alc260_dac_nids,
6351 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6352 .adc_nids = alc260_adc_nids,
6353 .dig_out_nid = ALC260_DIGOUT_NID,
6354 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6355 .channel_mode = alc260_modes,
6356 .input_mux = &alc260_capture_source,
6357 },
6358 [ALC260_REPLACER_672V] = {
f9e336f6 6359 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6360 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6361 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6362 .dac_nids = alc260_dac_nids,
6363 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6364 .adc_nids = alc260_adc_nids,
6365 .dig_out_nid = ALC260_DIGOUT_NID,
6366 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6367 .channel_mode = alc260_modes,
6368 .input_mux = &alc260_capture_source,
6369 .unsol_event = alc260_replacer_672v_unsol_event,
6370 .init_hook = alc260_replacer_672v_automute,
6371 },
7cf51e48
JW
6372#ifdef CONFIG_SND_DEBUG
6373 [ALC260_TEST] = {
f9e336f6 6374 .mixers = { alc260_test_mixer },
7cf51e48
JW
6375 .init_verbs = { alc260_test_init_verbs },
6376 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6377 .dac_nids = alc260_test_dac_nids,
6378 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6379 .adc_nids = alc260_test_adc_nids,
6380 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6381 .channel_mode = alc260_modes,
a1e8d2da
JW
6382 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6383 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6384 },
6385#endif
df694daa
KY
6386};
6387
6388static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6389{
6390 struct alc_spec *spec;
df694daa 6391 int err, board_config;
1da177e4 6392
e560d8d8 6393 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6394 if (spec == NULL)
6395 return -ENOMEM;
6396
6397 codec->spec = spec;
6398
f5fcc13c
TI
6399 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6400 alc260_models,
6401 alc260_cfg_tbl);
6402 if (board_config < 0) {
9a11f1aa 6403 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6404 codec->chip_name);
df694daa 6405 board_config = ALC260_AUTO;
16ded525 6406 }
1da177e4 6407
df694daa
KY
6408 if (board_config == ALC260_AUTO) {
6409 /* automatic parse from the BIOS config */
6410 err = alc260_parse_auto_config(codec);
6411 if (err < 0) {
6412 alc_free(codec);
6413 return err;
f12ab1e0 6414 } else if (!err) {
9c7f852e
TI
6415 printk(KERN_INFO
6416 "hda_codec: Cannot set up configuration "
6417 "from BIOS. Using base mode...\n");
df694daa
KY
6418 board_config = ALC260_BASIC;
6419 }
a9430dd8 6420 }
e9edcee0 6421
680cd536
KK
6422 err = snd_hda_attach_beep_device(codec, 0x1);
6423 if (err < 0) {
6424 alc_free(codec);
6425 return err;
6426 }
6427
df694daa 6428 if (board_config != ALC260_AUTO)
e9c364c0 6429 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 6430
1da177e4
LT
6431 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6432 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6433
a3bcba38
TI
6434 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6435 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6436
4ef0ef19
TI
6437 if (!spec->adc_nids && spec->input_mux) {
6438 /* check whether NID 0x04 is valid */
6439 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 6440 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
6441 /* get type */
6442 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6443 spec->adc_nids = alc260_adc_nids_alt;
6444 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6445 } else {
6446 spec->adc_nids = alc260_adc_nids;
6447 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6448 }
6449 }
b59bdf3b 6450 set_capture_mixer(codec);
45bdd1c1 6451 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6452
2134ea4f
TI
6453 spec->vmaster_nid = 0x08;
6454
1da177e4 6455 codec->patch_ops = alc_patch_ops;
df694daa 6456 if (board_config == ALC260_AUTO)
ae6b813a 6457 spec->init_hook = alc260_auto_init;
cb53c626
TI
6458#ifdef CONFIG_SND_HDA_POWER_SAVE
6459 if (!spec->loopback.amplist)
6460 spec->loopback.amplist = alc260_loopbacks;
6461#endif
daead538 6462 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
6463
6464 return 0;
6465}
6466
e9edcee0 6467
1da177e4 6468/*
4953550a 6469 * ALC882/883/885/888/889 support
1da177e4
LT
6470 *
6471 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6472 * configuration. Each pin widget can choose any input DACs and a mixer.
6473 * Each ADC is connected from a mixer of all inputs. This makes possible
6474 * 6-channel independent captures.
6475 *
6476 * In addition, an independent DAC for the multi-playback (not used in this
6477 * driver yet).
6478 */
df694daa
KY
6479#define ALC882_DIGOUT_NID 0x06
6480#define ALC882_DIGIN_NID 0x0a
4953550a
TI
6481#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6482#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6483#define ALC1200_DIGOUT_NID 0x10
6484
1da177e4 6485
d2a6d7dc 6486static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6487 { 8, NULL }
6488};
6489
4953550a 6490/* DACs */
1da177e4
LT
6491static hda_nid_t alc882_dac_nids[4] = {
6492 /* front, rear, clfe, rear_surr */
6493 0x02, 0x03, 0x04, 0x05
6494};
4953550a 6495#define alc883_dac_nids alc882_dac_nids
1da177e4 6496
4953550a 6497/* ADCs */
df694daa
KY
6498#define alc882_adc_nids alc880_adc_nids
6499#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
6500#define alc883_adc_nids alc882_adc_nids_alt
6501static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6502static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6503#define alc889_adc_nids alc880_adc_nids
1da177e4 6504
e1406348
TI
6505static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6506static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
6507#define alc883_capsrc_nids alc882_capsrc_nids_alt
6508static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6509#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 6510
1da177e4
LT
6511/* input MUX */
6512/* FIXME: should be a matrix-type input source selection */
6513
6514static struct hda_input_mux alc882_capture_source = {
6515 .num_items = 4,
6516 .items = {
6517 { "Mic", 0x0 },
6518 { "Front Mic", 0x1 },
6519 { "Line", 0x2 },
6520 { "CD", 0x4 },
6521 },
6522};
41d5545d 6523
4953550a
TI
6524#define alc883_capture_source alc882_capture_source
6525
87a8c370
JK
6526static struct hda_input_mux alc889_capture_source = {
6527 .num_items = 3,
6528 .items = {
6529 { "Front Mic", 0x0 },
6530 { "Mic", 0x3 },
6531 { "Line", 0x2 },
6532 },
6533};
6534
41d5545d
KS
6535static struct hda_input_mux mb5_capture_source = {
6536 .num_items = 3,
6537 .items = {
6538 { "Mic", 0x1 },
6539 { "Line", 0x2 },
6540 { "CD", 0x4 },
6541 },
6542};
6543
4953550a
TI
6544static struct hda_input_mux alc883_3stack_6ch_intel = {
6545 .num_items = 4,
6546 .items = {
6547 { "Mic", 0x1 },
6548 { "Front Mic", 0x0 },
6549 { "Line", 0x2 },
6550 { "CD", 0x4 },
6551 },
6552};
6553
6554static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6555 .num_items = 2,
6556 .items = {
6557 { "Mic", 0x1 },
6558 { "Line", 0x2 },
6559 },
6560};
6561
6562static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6563 .num_items = 4,
6564 .items = {
6565 { "Mic", 0x0 },
6566 { "iMic", 0x1 },
6567 { "Line", 0x2 },
6568 { "CD", 0x4 },
6569 },
6570};
6571
6572static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6573 .num_items = 2,
6574 .items = {
6575 { "Mic", 0x0 },
6576 { "Int Mic", 0x1 },
6577 },
6578};
6579
6580static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6581 .num_items = 3,
6582 .items = {
6583 { "Mic", 0x0 },
6584 { "Front Mic", 0x1 },
6585 { "Line", 0x4 },
6586 },
6587};
6588
6589static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6590 .num_items = 2,
6591 .items = {
6592 { "Mic", 0x0 },
6593 { "Line", 0x2 },
6594 },
6595};
6596
6597static struct hda_input_mux alc889A_mb31_capture_source = {
6598 .num_items = 2,
6599 .items = {
6600 { "Mic", 0x0 },
6601 /* Front Mic (0x01) unused */
6602 { "Line", 0x2 },
6603 /* Line 2 (0x03) unused */
6604 /* CD (0x04) unsused? */
6605 },
6606};
6607
6608/*
6609 * 2ch mode
6610 */
6611static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6612 { 2, NULL }
6613};
6614
272a527c
KY
6615/*
6616 * 2ch mode
6617 */
6618static struct hda_verb alc882_3ST_ch2_init[] = {
6619 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6620 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6621 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6622 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6623 { } /* end */
6624};
6625
4953550a
TI
6626/*
6627 * 4ch mode
6628 */
6629static struct hda_verb alc882_3ST_ch4_init[] = {
6630 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6631 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6634 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6635 { } /* end */
6636};
6637
272a527c
KY
6638/*
6639 * 6ch mode
6640 */
6641static struct hda_verb alc882_3ST_ch6_init[] = {
6642 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6643 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6644 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6645 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6646 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6647 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6648 { } /* end */
6649};
6650
4953550a 6651static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 6652 { 2, alc882_3ST_ch2_init },
4953550a 6653 { 4, alc882_3ST_ch4_init },
272a527c
KY
6654 { 6, alc882_3ST_ch6_init },
6655};
6656
4953550a
TI
6657#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6658
df694daa
KY
6659/*
6660 * 6ch mode
6661 */
6662static struct hda_verb alc882_sixstack_ch6_init[] = {
6663 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6664 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6665 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6666 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6667 { } /* end */
6668};
6669
6670/*
6671 * 8ch mode
6672 */
6673static struct hda_verb alc882_sixstack_ch8_init[] = {
6674 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6675 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6676 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6677 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6678 { } /* end */
6679};
6680
6681static struct hda_channel_mode alc882_sixstack_modes[2] = {
6682 { 6, alc882_sixstack_ch6_init },
6683 { 8, alc882_sixstack_ch8_init },
6684};
6685
87350ad0 6686/*
def319f9 6687 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
6688 */
6689
6690/*
6691 * 2ch mode
6692 */
6693static struct hda_verb alc885_mbp_ch2_init[] = {
6694 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6695 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6696 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6697 { } /* end */
6698};
6699
6700/*
a3f730af 6701 * 4ch mode
87350ad0 6702 */
a3f730af 6703static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
6704 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6705 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6706 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6707 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6708 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6709 { } /* end */
6710};
6711
a3f730af 6712static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 6713 { 2, alc885_mbp_ch2_init },
a3f730af 6714 { 4, alc885_mbp_ch4_init },
87350ad0
TI
6715};
6716
92b9de83
KS
6717/*
6718 * 2ch
6719 * Speakers/Woofer/HP = Front
6720 * LineIn = Input
6721 */
6722static struct hda_verb alc885_mb5_ch2_init[] = {
6723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6725 { } /* end */
6726};
6727
6728/*
6729 * 6ch mode
6730 * Speakers/HP = Front
6731 * Woofer = LFE
6732 * LineIn = Surround
6733 */
6734static struct hda_verb alc885_mb5_ch6_init[] = {
6735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6737 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6738 { } /* end */
6739};
6740
6741static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6742 { 2, alc885_mb5_ch2_init },
6743 { 6, alc885_mb5_ch6_init },
6744};
87350ad0 6745
4953550a
TI
6746
6747/*
6748 * 2ch mode
6749 */
6750static struct hda_verb alc883_4ST_ch2_init[] = {
6751 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6752 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6755 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6756 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6757 { } /* end */
6758};
6759
6760/*
6761 * 4ch mode
6762 */
6763static struct hda_verb alc883_4ST_ch4_init[] = {
6764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6765 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6766 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6767 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6768 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6769 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6770 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6771 { } /* end */
6772};
6773
6774/*
6775 * 6ch mode
6776 */
6777static struct hda_verb alc883_4ST_ch6_init[] = {
6778 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6779 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6780 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6781 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6782 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6783 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6784 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6785 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6786 { } /* end */
6787};
6788
6789/*
6790 * 8ch mode
6791 */
6792static struct hda_verb alc883_4ST_ch8_init[] = {
6793 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6794 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6795 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6796 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6797 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6798 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6799 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6800 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6801 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6802 { } /* end */
6803};
6804
6805static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6806 { 2, alc883_4ST_ch2_init },
6807 { 4, alc883_4ST_ch4_init },
6808 { 6, alc883_4ST_ch6_init },
6809 { 8, alc883_4ST_ch8_init },
6810};
6811
6812
6813/*
6814 * 2ch mode
6815 */
6816static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6817 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6818 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6819 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6820 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6821 { } /* end */
6822};
6823
6824/*
6825 * 4ch mode
6826 */
6827static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6828 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6829 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6830 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6831 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6832 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6833 { } /* end */
6834};
6835
6836/*
6837 * 6ch mode
6838 */
6839static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6840 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6841 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6842 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6843 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6844 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6845 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6846 { } /* end */
6847};
6848
6849static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6850 { 2, alc883_3ST_ch2_intel_init },
6851 { 4, alc883_3ST_ch4_intel_init },
6852 { 6, alc883_3ST_ch6_intel_init },
6853};
6854
dd7714c9
WF
6855/*
6856 * 2ch mode
6857 */
6858static struct hda_verb alc889_ch2_intel_init[] = {
6859 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6860 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6861 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6862 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6865 { } /* end */
6866};
6867
87a8c370
JK
6868/*
6869 * 6ch mode
6870 */
6871static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
6872 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6873 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6874 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6875 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6876 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
6877 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6878 { } /* end */
6879};
6880
6881/*
6882 * 8ch mode
6883 */
6884static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
6885 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6886 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6887 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6888 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6889 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
6890 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6891 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
6892 { } /* end */
6893};
6894
dd7714c9
WF
6895static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6896 { 2, alc889_ch2_intel_init },
87a8c370
JK
6897 { 6, alc889_ch6_intel_init },
6898 { 8, alc889_ch8_intel_init },
6899};
6900
4953550a
TI
6901/*
6902 * 6ch mode
6903 */
6904static struct hda_verb alc883_sixstack_ch6_init[] = {
6905 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6906 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6907 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6908 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6909 { } /* end */
6910};
6911
6912/*
6913 * 8ch mode
6914 */
6915static struct hda_verb alc883_sixstack_ch8_init[] = {
6916 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6917 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6918 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6919 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6920 { } /* end */
6921};
6922
6923static struct hda_channel_mode alc883_sixstack_modes[2] = {
6924 { 6, alc883_sixstack_ch6_init },
6925 { 8, alc883_sixstack_ch8_init },
6926};
6927
6928
1da177e4
LT
6929/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6930 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6931 */
c8b6bf9b 6932static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 6933 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 6934 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 6935 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 6936 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
6937 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6938 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
6939 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6940 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 6941 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 6942 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
6943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6949 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
6950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6952 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 6953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
6954 { } /* end */
6955};
6956
87350ad0 6957static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
6958 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6959 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
6960 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6961 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
6962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
6963 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6964 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
6965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6966 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 6967 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
6968 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6969 { } /* end */
6970};
41d5545d
KS
6971
6972static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
6973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6974 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6976 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6977 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6978 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6979 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6980 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
41d5545d
KS
6981 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6982 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6984 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6985 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6986 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6987 { } /* end */
6988};
92b9de83 6989
bdd148a3
KY
6990static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6991 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6992 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6998 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6999 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7000 { } /* end */
7001};
7002
272a527c
KY
7003static struct snd_kcontrol_new alc882_targa_mixer[] = {
7004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7007 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7008 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7009 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7010 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7013 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7016 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7017 { } /* end */
7018};
7019
7020/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7021 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7022 */
7023static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7024 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7025 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7027 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7028 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7029 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7030 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7031 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7032 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7033 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7036 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7037 { } /* end */
7038};
7039
914759b7
TI
7040static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7041 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7042 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7043 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7044 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7045 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7049 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7050 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7051 { } /* end */
7052};
7053
df694daa
KY
7054static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7055 {
7056 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7057 .name = "Channel Mode",
7058 .info = alc_ch_mode_info,
7059 .get = alc_ch_mode_get,
7060 .put = alc_ch_mode_put,
7061 },
7062 { } /* end */
7063};
7064
4953550a 7065static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7066 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7070 /* Rear mixer */
05acb863
TI
7071 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7072 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7074 /* CLFE mixer */
05acb863
TI
7075 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7076 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7077 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7078 /* Side mixer */
05acb863
TI
7079 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7080 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7081 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7082
cb638122
TI
7083 /* mute analog input loopbacks */
7084 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7085 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7086 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7089
e9edcee0 7090 /* Front Pin: output 0 (0x0c) */
05acb863 7091 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7093 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7094 /* Rear Pin: output 1 (0x0d) */
05acb863 7095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7096 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7098 /* CLFE Pin: output 2 (0x0e) */
05acb863 7099 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7100 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7101 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7102 /* Side Pin: output 3 (0x0f) */
05acb863 7103 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7104 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7105 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7106 /* Mic (rear) pin: input vref at 80% */
16ded525 7107 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7108 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7109 /* Front Mic pin: input vref at 80% */
16ded525 7110 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7111 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7112 /* Line In pin: input */
05acb863 7113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7115 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7116 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7117 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7118 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7119 /* CD pin widget for input */
05acb863 7120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7121
7122 /* FIXME: use matrix-type input source selection */
7123 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7124 /* Input mixer2 */
05acb863
TI
7125 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 7129 /* Input mixer3 */
05acb863
TI
7130 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
05acb863
TI
7134 /* ADC2: mute amp left and right */
7135 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7136 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7137 /* ADC3: mute amp left and right */
7138 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7139 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7140
7141 { }
7142};
7143
4953550a
TI
7144static struct hda_verb alc882_adc1_init_verbs[] = {
7145 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7147 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7150 /* ADC1: mute amp left and right */
7151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7152 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7153 { }
7154};
7155
4b146cb0
TI
7156static struct hda_verb alc882_eapd_verbs[] = {
7157 /* change to EAPD mode */
7158 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7159 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7160 { }
4b146cb0
TI
7161};
7162
87a8c370
JK
7163static struct hda_verb alc889_eapd_verbs[] = {
7164 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7165 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7166 { }
7167};
7168
6732bd0d
WF
7169static struct hda_verb alc_hp15_unsol_verbs[] = {
7170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7171 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7172 {}
7173};
87a8c370
JK
7174
7175static struct hda_verb alc885_init_verbs[] = {
7176 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7180 /* Rear mixer */
7181 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7184 /* CLFE mixer */
7185 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7186 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7187 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7188 /* Side mixer */
7189 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7190 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7191 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7192
7193 /* mute analog input loopbacks */
7194 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7195 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7196 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7197
7198 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7201 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7202 /* Front Pin: output 0 (0x0c) */
7203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7204 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7205 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7206 /* Rear Pin: output 1 (0x0d) */
7207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7209 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7210 /* CLFE Pin: output 2 (0x0e) */
7211 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7212 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7213 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7214 /* Side Pin: output 3 (0x0f) */
7215 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7216 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7217 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7218 /* Mic (rear) pin: input vref at 80% */
7219 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7220 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7221 /* Front Mic pin: input vref at 80% */
7222 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7223 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7224 /* Line In pin: input */
7225 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7226 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7227
7228 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7229 /* Input mixer1 */
7230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7233 /* Input mixer2 */
7234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7235 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7237 /* Input mixer3 */
7238 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7240 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7241 /* ADC2: mute amp left and right */
7242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7243 /* ADC3: mute amp left and right */
7244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7245
7246 { }
7247};
7248
7249static struct hda_verb alc885_init_input_verbs[] = {
7250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7253 { }
7254};
7255
7256
7257/* Unmute Selector 24h and set the default input to front mic */
7258static struct hda_verb alc889_init_input_verbs[] = {
7259 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7260 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7261 { }
7262};
7263
7264
4953550a
TI
7265#define alc883_init_verbs alc882_base_init_verbs
7266
9102cd1c
TD
7267/* Mac Pro test */
7268static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7270 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7271 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7272 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7273 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7274 /* FIXME: this looks suspicious...
9102cd1c
TD
7275 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
7276 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7277 */
9102cd1c
TD
7278 { } /* end */
7279};
7280
7281static struct hda_verb alc882_macpro_init_verbs[] = {
7282 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7284 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7285 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7286 /* Front Pin: output 0 (0x0c) */
7287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7288 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7289 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7290 /* Front Mic pin: input vref at 80% */
7291 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7292 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7293 /* Speaker: output */
7294 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7295 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7296 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7297 /* Headphone output (output 0 - 0x0c) */
7298 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7300 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7301
7302 /* FIXME: use matrix-type input source selection */
7303 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7304 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7309 /* Input mixer2 */
7310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7314 /* Input mixer3 */
7315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7319 /* ADC1: mute amp left and right */
7320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7321 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7322 /* ADC2: mute amp left and right */
7323 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7325 /* ADC3: mute amp left and right */
7326 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7327 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7328
7329 { }
7330};
f12ab1e0 7331
41d5545d
KS
7332/* Macbook 5,1 */
7333static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7334 /* DACs */
7335 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7336 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7337 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7338 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7339 /* Front mixer */
41d5545d
KS
7340 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7341 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7343 /* Surround mixer */
7344 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7345 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7347 /* LFE mixer */
7348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7350 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7351 /* HP mixer */
7352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7353 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7355 /* Front Pin (0x0c) */
41d5545d
KS
7356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
7358 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7359 /* LFE Pin (0x0e) */
7360 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7361 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7362 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7363 /* HP Pin (0x0f) */
41d5545d
KS
7364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7365 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 7366 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
41d5545d
KS
7367 /* Front Mic pin: input vref at 80% */
7368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7370 /* Line In pin */
7371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7373
7374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7378 { }
7379};
7380
87350ad0
TI
7381/* Macbook Pro rev3 */
7382static struct hda_verb alc885_mbp3_init_verbs[] = {
7383 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7387 /* Rear mixer */
7388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7390 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
7391 /* HP mixer */
7392 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7393 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
7395 /* Front Pin: output 0 (0x0c) */
7396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7397 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7398 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 7399 /* HP Pin: output 0 (0x0e) */
87350ad0 7400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
7401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7402 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
7403 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7404 /* Mic (rear) pin: input vref at 80% */
7405 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7406 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7407 /* Front Mic pin: input vref at 80% */
7408 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7409 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7410 /* Line In pin: use output 1 when in LineOut mode */
7411 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7412 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7413 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7414
7415 /* FIXME: use matrix-type input source selection */
7416 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7417 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7418 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7419 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7420 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7422 /* Input mixer2 */
7423 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7424 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7425 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7427 /* Input mixer3 */
7428 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7429 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7430 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7432 /* ADC1: mute amp left and right */
7433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7434 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7435 /* ADC2: mute amp left and right */
7436 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7437 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7438 /* ADC3: mute amp left and right */
7439 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7440 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7441
7442 { }
7443};
7444
c54728d8
NF
7445/* iMac 24 mixer. */
7446static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7447 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7448 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7449 { } /* end */
7450};
7451
7452/* iMac 24 init verbs. */
7453static struct hda_verb alc885_imac24_init_verbs[] = {
7454 /* Internal speakers: output 0 (0x0c) */
7455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7457 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7458 /* Internal speakers: output 0 (0x0c) */
7459 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7460 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7461 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7462 /* Headphone: output 0 (0x0c) */
7463 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7464 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7465 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7466 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7467 /* Front Mic: input vref at 80% */
7468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7469 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7470 { }
7471};
7472
7473/* Toggle speaker-output according to the hp-jack state */
4f5d1706 7474static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 7475{
a9fd4f3f 7476 struct alc_spec *spec = codec->spec;
c54728d8 7477
a9fd4f3f
TI
7478 spec->autocfg.hp_pins[0] = 0x14;
7479 spec->autocfg.speaker_pins[0] = 0x18;
7480 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
7481}
7482
4f5d1706 7483static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 7484{
a9fd4f3f 7485 struct alc_spec *spec = codec->spec;
87350ad0 7486
a9fd4f3f
TI
7487 spec->autocfg.hp_pins[0] = 0x15;
7488 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
7489}
7490
7491
272a527c
KY
7492static struct hda_verb alc882_targa_verbs[] = {
7493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7495
7496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7497 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7498
272a527c
KY
7499 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7500 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7501 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7502
7503 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
7504 { } /* end */
7505};
7506
7507/* toggle speaker-output according to the hp-jack state */
7508static void alc882_targa_automute(struct hda_codec *codec)
7509{
a9fd4f3f
TI
7510 struct alc_spec *spec = codec->spec;
7511 alc_automute_amp(codec);
82beb8fd 7512 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
7513 spec->jack_present ? 1 : 3);
7514}
7515
4f5d1706 7516static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
7517{
7518 struct alc_spec *spec = codec->spec;
7519
7520 spec->autocfg.hp_pins[0] = 0x14;
7521 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
7522}
7523
7524static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7525{
a9fd4f3f 7526 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 7527 alc882_targa_automute(codec);
272a527c
KY
7528}
7529
7530static struct hda_verb alc882_asus_a7j_verbs[] = {
7531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7533
7534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7536 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7537
272a527c
KY
7538 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7539 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7540 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7541
7542 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7543 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7544 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7545 { } /* end */
7546};
7547
914759b7
TI
7548static struct hda_verb alc882_asus_a7m_verbs[] = {
7549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7551
7552 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7554 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7555
914759b7
TI
7556 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7557 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7558 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7559
7560 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7561 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7562 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7563 { } /* end */
7564};
7565
9102cd1c
TD
7566static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7567{
7568 unsigned int gpiostate, gpiomask, gpiodir;
7569
7570 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7571 AC_VERB_GET_GPIO_DATA, 0);
7572
7573 if (!muted)
7574 gpiostate |= (1 << pin);
7575 else
7576 gpiostate &= ~(1 << pin);
7577
7578 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7579 AC_VERB_GET_GPIO_MASK, 0);
7580 gpiomask |= (1 << pin);
7581
7582 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7583 AC_VERB_GET_GPIO_DIRECTION, 0);
7584 gpiodir |= (1 << pin);
7585
7586
7587 snd_hda_codec_write(codec, codec->afg, 0,
7588 AC_VERB_SET_GPIO_MASK, gpiomask);
7589 snd_hda_codec_write(codec, codec->afg, 0,
7590 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7591
7592 msleep(1);
7593
7594 snd_hda_codec_write(codec, codec->afg, 0,
7595 AC_VERB_SET_GPIO_DATA, gpiostate);
7596}
7597
7debbe51
TI
7598/* set up GPIO at initialization */
7599static void alc885_macpro_init_hook(struct hda_codec *codec)
7600{
7601 alc882_gpio_mute(codec, 0, 0);
7602 alc882_gpio_mute(codec, 1, 0);
7603}
7604
7605/* set up GPIO and update auto-muting at initialization */
7606static void alc885_imac24_init_hook(struct hda_codec *codec)
7607{
7608 alc885_macpro_init_hook(codec);
4f5d1706 7609 alc_automute_amp(codec);
7debbe51
TI
7610}
7611
df694daa
KY
7612/*
7613 * generic initialization of ADC, input mixers and output mixers
7614 */
4953550a 7615static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
7616 /*
7617 * Unmute ADC0-2 and set the default input to mic-in
7618 */
4953550a
TI
7619 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 7623
4953550a
TI
7624 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7625 * mixer widget
7626 * Note: PASD motherboards uses the Line In 2 as the input for
7627 * front panel mic (mic 2)
7628 */
7629 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7631 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
17bba1b7 7635
4953550a
TI
7636 /*
7637 * Set up output mixers (0x0c - 0x0f)
7638 */
7639 /* set vol=0 to output mixers */
7640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7641 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7642 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7643 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7644 /* set up input amps for analog loopback */
7645 /* Amp Indices: DAC = 0, mixer = 1 */
7646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7652 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7654 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7655 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 7656
4953550a
TI
7657 /* FIXME: use matrix-type input source selection */
7658 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7659 /* Input mixer2 */
7660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7664 /* Input mixer3 */
7665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9c7f852e 7669
4953550a 7670 { }
9c7f852e
TI
7671};
7672
eb4c41d3
TS
7673/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7674static struct hda_verb alc889A_mb31_ch2_init[] = {
7675 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7676 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7677 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7678 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7679 { } /* end */
7680};
7681
7682/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7683static struct hda_verb alc889A_mb31_ch4_init[] = {
7684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7685 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7686 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7687 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7688 { } /* end */
7689};
7690
7691/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7692static struct hda_verb alc889A_mb31_ch5_init[] = {
7693 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7694 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7697 { } /* end */
7698};
7699
7700/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7701static struct hda_verb alc889A_mb31_ch6_init[] = {
7702 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7703 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7704 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7705 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7706 { } /* end */
7707};
7708
7709static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7710 { 2, alc889A_mb31_ch2_init },
7711 { 4, alc889A_mb31_ch4_init },
7712 { 5, alc889A_mb31_ch5_init },
7713 { 6, alc889A_mb31_ch6_init },
7714};
7715
b373bdeb
AN
7716static struct hda_verb alc883_medion_eapd_verbs[] = {
7717 /* eanable EAPD on medion laptop */
7718 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7719 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7720 { }
7721};
7722
4953550a 7723#define alc883_base_mixer alc882_base_mixer
834be88d 7724
a8848bd6
AS
7725static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7726 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7727 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7728 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7729 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7730 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7731 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7732 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7734 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7737 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7738 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
7739 { } /* end */
7740};
7741
0c4cc443 7742static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7743 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7744 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7745 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7746 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7747 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7748 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7750 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7751 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7752 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
7753 { } /* end */
7754};
7755
fb97dc67
J
7756static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7757 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7758 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7759 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7760 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7762 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7764 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7765 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7766 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
7767 { } /* end */
7768};
7769
9c7f852e
TI
7770static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7771 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7772 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7773 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7774 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7775 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7776 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7777 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7779 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7781 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7782 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7783 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7784 { } /* end */
7785};
df694daa 7786
9c7f852e
TI
7787static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7788 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7789 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7790 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7791 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7792 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7793 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7794 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7795 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7796 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7799 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7800 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7801 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7802 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7804 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7805 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7806 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7807 { } /* end */
7808};
7809
17bba1b7
J
7810static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7811 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7812 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7813 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7814 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7815 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7816 HDA_OUTPUT),
7817 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7818 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7819 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7821 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7822 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7823 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7824 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7825 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7829 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7830 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
7831 { } /* end */
7832};
7833
87a8c370
JK
7834static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7836 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7838 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7839 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7840 HDA_OUTPUT),
7841 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7842 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7843 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7844 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7845 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7847 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7848 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7850 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7851 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7854 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7855 { } /* end */
7856};
7857
d1d985f0 7858static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7859 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7860 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7861 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7862 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7863 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7864 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7865 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7866 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7870 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7871 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7873 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7874 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7875 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7876 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 7877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
7878 { } /* end */
7879};
7880
c259249f 7881static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce
KY
7882 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7884 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7885 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7886 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7887 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7888 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7889 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7890 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7896 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 7898 { } /* end */
f12ab1e0 7899};
ccc656ce 7900
c259249f 7901static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce
KY
7902 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7904 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7905 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7906 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7908 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7910 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7911 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7912 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 7913 { } /* end */
f12ab1e0 7914};
ccc656ce 7915
bc9f98a9
KY
7916static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7918 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7919 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7920 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7921 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7922 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 7925 { } /* end */
f12ab1e0 7926};
bc9f98a9 7927
272a527c
KY
7928static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7929 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7930 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7936 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7937 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
7938 { } /* end */
7939};
7940
7941static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7942 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7944 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7945 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7946 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7947 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7948 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7950 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 7951 { } /* end */
ea1fb29a 7952};
272a527c 7953
2880a867 7954static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7955 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7956 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7957 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7958 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7959 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7960 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7961 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7962 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 7963 { } /* end */
d1a991a6 7964};
2880a867 7965
d2fd4b09
TV
7966static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
7967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7968 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7969 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7970 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
684a8842
TV
7971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
7973 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7974 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7978 { } /* end */
7979};
7980
e2757d5e
KY
7981static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7983 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7985 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7986 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7987 0x0d, 1, 0x0, HDA_OUTPUT),
7988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7991 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7992 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
7993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7998 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7999 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8000 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8001 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8002 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8003 { } /* end */
8004};
8005
eb4c41d3
TS
8006static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8007 /* Output mixers */
8008 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8009 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8011 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8012 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8013 HDA_OUTPUT),
8014 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8015 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8016 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8017 /* Output switches */
8018 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8019 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8020 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8021 /* Boost mixers */
8022 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8024 /* Input mixers */
8025 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8026 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8027 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8028 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8029 { } /* end */
8030};
8031
3e1647c5
GG
8032static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8033 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8034 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8039 { } /* end */
8040};
8041
e2757d5e
KY
8042static struct hda_bind_ctls alc883_bind_cap_vol = {
8043 .ops = &snd_hda_bind_vol,
8044 .values = {
8045 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8046 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8047 0
8048 },
8049};
8050
8051static struct hda_bind_ctls alc883_bind_cap_switch = {
8052 .ops = &snd_hda_bind_sw,
8053 .values = {
8054 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8055 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8056 0
8057 },
8058};
8059
8060static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8061 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8062 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8064 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8065 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8066 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8067 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8069 { } /* end */
8070};
df694daa 8071
4953550a
TI
8072static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8073 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8074 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8075 {
8076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8077 /* .name = "Capture Source", */
8078 .name = "Input Source",
8079 .count = 1,
8080 .info = alc_mux_enum_info,
8081 .get = alc_mux_enum_get,
8082 .put = alc_mux_enum_put,
8083 },
8084 { } /* end */
8085};
9c7f852e 8086
4953550a
TI
8087static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8088 {
8089 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8090 .name = "Channel Mode",
8091 .info = alc_ch_mode_info,
8092 .get = alc_ch_mode_get,
8093 .put = alc_ch_mode_put,
8094 },
8095 { } /* end */
9c7f852e
TI
8096};
8097
a8848bd6 8098/* toggle speaker-output according to the hp-jack state */
4f5d1706 8099static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8100{
a9fd4f3f 8101 struct alc_spec *spec = codec->spec;
a8848bd6 8102
a9fd4f3f
TI
8103 spec->autocfg.hp_pins[0] = 0x15;
8104 spec->autocfg.speaker_pins[0] = 0x14;
8105 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8106}
8107
8108/* auto-toggle front mic */
8109/*
8110static void alc883_mitac_mic_automute(struct hda_codec *codec)
8111{
8112 unsigned int present;
8113 unsigned char bits;
8114
8115 present = snd_hda_codec_read(codec, 0x18, 0,
8116 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8117 bits = present ? HDA_AMP_MUTE : 0;
8118 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8119}
8120*/
8121
a8848bd6
AS
8122static struct hda_verb alc883_mitac_verbs[] = {
8123 /* HP */
8124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8126 /* Subwoofer */
8127 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8128 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8129
8130 /* enable unsolicited event */
8131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8132 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8133
8134 { } /* end */
8135};
8136
0c4cc443 8137static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8138 /* HP */
8139 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8141 /* Int speaker */
8142 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8144
8145 /* enable unsolicited event */
8146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8148
8149 { } /* end */
8150};
8151
fb97dc67
J
8152static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8153 /* HP */
8154 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8155 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8156 /* Subwoofer */
8157 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8158 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8159
8160 /* enable unsolicited event */
8161 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8162
8163 { } /* end */
8164};
8165
c259249f 8166static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8167 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8169
8170 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8171 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8172
64a8be74
DH
8173/* Connect Line-Out side jack (SPDIF) to Side */
8174 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8175 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8176 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8177/* Connect Mic jack to CLFE */
8178 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8179 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8180 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8181/* Connect Line-in jack to Surround */
8182 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8183 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8184 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8185/* Connect HP out jack to Front */
8186 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8187 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
8189
8190 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
8191
8192 { } /* end */
8193};
8194
bc9f98a9
KY
8195static struct hda_verb alc883_lenovo_101e_verbs[] = {
8196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8197 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8198 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8199 { } /* end */
8200};
8201
272a527c
KY
8202static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8205 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8207 { } /* end */
8208};
8209
8210static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8214 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8215 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8216 { } /* end */
8217};
8218
189609ae
KY
8219static struct hda_verb alc883_haier_w66_verbs[] = {
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8222
8223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8224
8225 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8226 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8227 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8229 { } /* end */
8230};
8231
e2757d5e
KY
8232static struct hda_verb alc888_lenovo_sky_verbs[] = {
8233 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8234 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8235 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8236 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8238 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8239 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8240 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8241 { } /* end */
8242};
8243
8718b700
HRK
8244static struct hda_verb alc888_6st_dell_verbs[] = {
8245 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8246 { }
8247};
8248
3e1647c5
GG
8249static struct hda_verb alc883_vaiott_verbs[] = {
8250 /* HP */
8251 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8253
8254 /* enable unsolicited event */
8255 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8256
8257 { } /* end */
8258};
8259
4f5d1706 8260static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 8261{
a9fd4f3f 8262 struct alc_spec *spec = codec->spec;
8718b700 8263
a9fd4f3f
TI
8264 spec->autocfg.hp_pins[0] = 0x1b;
8265 spec->autocfg.speaker_pins[0] = 0x14;
8266 spec->autocfg.speaker_pins[1] = 0x16;
8267 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
8268}
8269
4723c022 8270static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8271 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8272 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8273 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8274 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8275 { } /* end */
5795b9e6
CM
8276};
8277
3ea0d7cf
HRK
8278/*
8279 * 2ch mode
8280 */
4723c022 8281static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8282 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8283 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8284 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8285 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8286 { } /* end */
8341de60
CM
8287};
8288
3ea0d7cf
HRK
8289/*
8290 * 4ch mode
8291 */
8292static struct hda_verb alc888_3st_hp_4ch_init[] = {
8293 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8294 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8295 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8296 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8297 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8298 { } /* end */
8299};
8300
8301/*
8302 * 6ch mode
8303 */
4723c022 8304static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8305 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8306 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8307 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8308 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8309 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8310 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8311 { } /* end */
8341de60
CM
8312};
8313
3ea0d7cf 8314static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8315 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8316 { 4, alc888_3st_hp_4ch_init },
4723c022 8317 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8318};
8319
272a527c
KY
8320/* toggle front-jack and RCA according to the hp-jack state */
8321static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8322{
8323 unsigned int present;
ea1fb29a 8324
272a527c
KY
8325 present = snd_hda_codec_read(codec, 0x1b, 0,
8326 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8327 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8328 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8329 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8330 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8331}
8332
8333/* toggle RCA according to the front-jack state */
8334static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8335{
8336 unsigned int present;
ea1fb29a 8337
272a527c
KY
8338 present = snd_hda_codec_read(codec, 0x14, 0,
8339 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8340 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8341 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8342}
47fd830a 8343
272a527c
KY
8344static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8345 unsigned int res)
8346{
8347 if ((res >> 26) == ALC880_HP_EVENT)
8348 alc888_lenovo_ms7195_front_automute(codec);
8349 if ((res >> 26) == ALC880_FRONT_EVENT)
8350 alc888_lenovo_ms7195_rca_automute(codec);
8351}
8352
8353static struct hda_verb alc883_medion_md2_verbs[] = {
8354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8356
8357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8358
8359 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8360 { } /* end */
8361};
8362
8363/* toggle speaker-output according to the hp-jack state */
4f5d1706 8364static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 8365{
a9fd4f3f 8366 struct alc_spec *spec = codec->spec;
272a527c 8367
a9fd4f3f
TI
8368 spec->autocfg.hp_pins[0] = 0x14;
8369 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
8370}
8371
ccc656ce 8372/* toggle speaker-output according to the hp-jack state */
c259249f
SA
8373#define alc883_targa_init_hook alc882_targa_init_hook
8374#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 8375
0c4cc443
HRK
8376static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8377{
8378 unsigned int present;
8379
8380 present = snd_hda_codec_read(codec, 0x18, 0,
8381 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8382 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8383 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8384}
8385
4f5d1706 8386static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 8387{
a9fd4f3f
TI
8388 struct alc_spec *spec = codec->spec;
8389
8390 spec->autocfg.hp_pins[0] = 0x15;
8391 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
8392}
8393
8394static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8395{
a9fd4f3f 8396 alc_automute_amp(codec);
0c4cc443
HRK
8397 alc883_clevo_m720_mic_automute(codec);
8398}
8399
8400static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8401 unsigned int res)
8402{
0c4cc443 8403 switch (res >> 26) {
0c4cc443
HRK
8404 case ALC880_MIC_EVENT:
8405 alc883_clevo_m720_mic_automute(codec);
8406 break;
a9fd4f3f
TI
8407 default:
8408 alc_automute_amp_unsol_event(codec, res);
8409 break;
0c4cc443 8410 }
368c7a95
J
8411}
8412
fb97dc67 8413/* toggle speaker-output according to the hp-jack state */
4f5d1706 8414static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 8415{
a9fd4f3f 8416 struct alc_spec *spec = codec->spec;
fb97dc67 8417
a9fd4f3f
TI
8418 spec->autocfg.hp_pins[0] = 0x14;
8419 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
8420}
8421
4f5d1706 8422static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 8423{
a9fd4f3f 8424 struct alc_spec *spec = codec->spec;
189609ae 8425
a9fd4f3f
TI
8426 spec->autocfg.hp_pins[0] = 0x1b;
8427 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
8428}
8429
bc9f98a9
KY
8430static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8431{
8432 unsigned int present;
f12ab1e0 8433 unsigned char bits;
bc9f98a9 8434
64a8be74
DH
8435 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8436 & AC_PINSENSE_PRESENCE;
47fd830a
TI
8437 bits = present ? HDA_AMP_MUTE : 0;
8438 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8439 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8440}
8441
8442static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8443{
8444 unsigned int present;
f12ab1e0 8445 unsigned char bits;
bc9f98a9
KY
8446
8447 present = snd_hda_codec_read(codec, 0x1b, 0,
8448 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8449 bits = present ? HDA_AMP_MUTE : 0;
8450 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8451 HDA_AMP_MUTE, bits);
8452 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8453 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8454}
8455
8456static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8457 unsigned int res)
8458{
8459 if ((res >> 26) == ALC880_HP_EVENT)
8460 alc883_lenovo_101e_all_automute(codec);
8461 if ((res >> 26) == ALC880_FRONT_EVENT)
8462 alc883_lenovo_101e_ispeaker_automute(codec);
8463}
8464
676a9b53 8465/* toggle speaker-output according to the hp-jack state */
4f5d1706 8466static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 8467{
a9fd4f3f 8468 struct alc_spec *spec = codec->spec;
676a9b53 8469
a9fd4f3f
TI
8470 spec->autocfg.hp_pins[0] = 0x14;
8471 spec->autocfg.speaker_pins[0] = 0x15;
8472 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
8473}
8474
d1a991a6
KY
8475static struct hda_verb alc883_acer_eapd_verbs[] = {
8476 /* HP Pin: output 0 (0x0c) */
8477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8479 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8480 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8483 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8484 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 /* eanable EAPD on medion laptop */
8486 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8487 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8488 /* enable unsolicited event */
8489 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8490 { }
8491};
8492
fc86f954
DK
8493static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8495 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8497 { } /* end */
8498};
8499
4f5d1706 8500static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 8501{
a9fd4f3f 8502 struct alc_spec *spec = codec->spec;
5795b9e6 8503
a9fd4f3f
TI
8504 spec->autocfg.hp_pins[0] = 0x1b;
8505 spec->autocfg.speaker_pins[0] = 0x14;
8506 spec->autocfg.speaker_pins[1] = 0x15;
8507 spec->autocfg.speaker_pins[2] = 0x16;
8508 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
8509}
8510
4f5d1706 8511static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 8512{
a9fd4f3f 8513 struct alc_spec *spec = codec->spec;
e2757d5e 8514
a9fd4f3f
TI
8515 spec->autocfg.hp_pins[0] = 0x1b;
8516 spec->autocfg.speaker_pins[0] = 0x14;
8517 spec->autocfg.speaker_pins[1] = 0x15;
8518 spec->autocfg.speaker_pins[2] = 0x16;
8519 spec->autocfg.speaker_pins[3] = 0x17;
8520 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
8521}
8522
4f5d1706 8523static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
8524{
8525 struct alc_spec *spec = codec->spec;
8526
8527 spec->autocfg.hp_pins[0] = 0x15;
8528 spec->autocfg.speaker_pins[0] = 0x14;
8529 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
8530}
8531
e2757d5e
KY
8532static struct hda_verb alc888_asus_m90v_verbs[] = {
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8534 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8536 /* enable unsolicited event */
8537 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8538 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8539 { } /* end */
8540};
8541
4f5d1706 8542static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 8543{
a9fd4f3f 8544 struct alc_spec *spec = codec->spec;
e2757d5e 8545
a9fd4f3f
TI
8546 spec->autocfg.hp_pins[0] = 0x1b;
8547 spec->autocfg.speaker_pins[0] = 0x14;
8548 spec->autocfg.speaker_pins[1] = 0x15;
8549 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
8550 spec->ext_mic.pin = 0x18;
8551 spec->int_mic.pin = 0x19;
8552 spec->ext_mic.mux_idx = 0;
8553 spec->int_mic.mux_idx = 1;
8554 spec->auto_mic = 1;
e2757d5e
KY
8555}
8556
8557static struct hda_verb alc888_asus_eee1601_verbs[] = {
8558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8560 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8563 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8564 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8565 /* enable unsolicited event */
8566 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8567 { } /* end */
8568};
8569
e2757d5e
KY
8570static void alc883_eee1601_inithook(struct hda_codec *codec)
8571{
a9fd4f3f
TI
8572 struct alc_spec *spec = codec->spec;
8573
8574 spec->autocfg.hp_pins[0] = 0x14;
8575 spec->autocfg.speaker_pins[0] = 0x1b;
8576 alc_automute_pin(codec);
e2757d5e
KY
8577}
8578
eb4c41d3
TS
8579static struct hda_verb alc889A_mb31_verbs[] = {
8580 /* Init rear pin (used as headphone output) */
8581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8582 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8583 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8584 /* Init line pin (used as output in 4ch and 6ch mode) */
8585 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8586 /* Init line 2 pin (used as headphone out by default) */
8587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8588 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8589 { } /* end */
8590};
8591
8592/* Mute speakers according to the headphone jack state */
8593static void alc889A_mb31_automute(struct hda_codec *codec)
8594{
8595 unsigned int present;
8596
8597 /* Mute only in 2ch or 4ch mode */
8598 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8599 == 0x00) {
8600 present = snd_hda_codec_read(codec, 0x15, 0,
8601 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8602 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8603 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8604 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8605 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8606 }
8607}
8608
8609static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8610{
8611 if ((res >> 26) == ALC880_HP_EVENT)
8612 alc889A_mb31_automute(codec);
8613}
8614
4953550a 8615
cb53c626 8616#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 8617#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
8618#endif
8619
def319f9 8620/* pcm configuration: identical with ALC880 */
4953550a
TI
8621#define alc882_pcm_analog_playback alc880_pcm_analog_playback
8622#define alc882_pcm_analog_capture alc880_pcm_analog_capture
8623#define alc882_pcm_digital_playback alc880_pcm_digital_playback
8624#define alc882_pcm_digital_capture alc880_pcm_digital_capture
8625
8626static hda_nid_t alc883_slave_dig_outs[] = {
8627 ALC1200_DIGOUT_NID, 0,
8628};
8629
8630static hda_nid_t alc1200_slave_dig_outs[] = {
8631 ALC883_DIGOUT_NID, 0,
8632};
9c7f852e
TI
8633
8634/*
8635 * configuration and preset
8636 */
4953550a
TI
8637static const char *alc882_models[ALC882_MODEL_LAST] = {
8638 [ALC882_3ST_DIG] = "3stack-dig",
8639 [ALC882_6ST_DIG] = "6stack-dig",
8640 [ALC882_ARIMA] = "arima",
8641 [ALC882_W2JC] = "w2jc",
8642 [ALC882_TARGA] = "targa",
8643 [ALC882_ASUS_A7J] = "asus-a7j",
8644 [ALC882_ASUS_A7M] = "asus-a7m",
8645 [ALC885_MACPRO] = "macpro",
8646 [ALC885_MB5] = "mb5",
8647 [ALC885_MBP3] = "mbp3",
8648 [ALC885_IMAC24] = "imac24",
8649 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
8650 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8651 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 8652 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
8653 [ALC883_TARGA_DIG] = "targa-dig",
8654 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 8655 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 8656 [ALC883_ACER] = "acer",
2880a867 8657 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 8658 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 8659 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 8660 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 8661 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 8662 [ALC883_MEDION] = "medion",
272a527c 8663 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8664 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8665 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8666 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8667 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8668 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8669 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8670 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8671 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8672 [ALC883_MITAC] = "mitac",
0c4cc443 8673 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8674 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 8675 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 8676 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
8677 [ALC889A_INTEL] = "intel-alc889a",
8678 [ALC889_INTEL] = "intel-x58",
3ab90935 8679 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 8680 [ALC889A_MB31] = "mb31",
3e1647c5 8681 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 8682 [ALC882_AUTO] = "auto",
f5fcc13c
TI
8683};
8684
4953550a
TI
8685static struct snd_pci_quirk alc882_cfg_tbl[] = {
8686 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8687
ac3e3741 8688 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 8689 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 8690 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
8691 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8692 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8693 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
8694 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8695 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd
LW
8696 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8697 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
8698 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8699 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
8700 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8701 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
8702 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8703 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 8704 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 8705 ALC888_ACER_ASPIRE_6530G),
cc374c47 8706 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 8707 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
8708 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
8709 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
8710 /* default Acer -- disabled as it causes more problems.
8711 * model=auto should work fine now
8712 */
8713 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 8714
5795b9e6 8715 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 8716
febe3375 8717 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8718 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8719 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8720 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 8721 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 8722 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
8723
8724 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8725 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8726 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 8727 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
8728 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8729 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8730 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 8731 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 8732 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 8733 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 8734 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
8735
8736 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 8737 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 8738 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 8739 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
8740 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8741 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8742 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8743 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
8744 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8745
6f3bf657 8746 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8747 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8748 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 8749 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
4383fae0 8750 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 8751 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 8752 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8753 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8754 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8755 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8756 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8757 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8758 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8759 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 8760 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8761 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8762 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8763 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
64a8be74 8764 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
8765 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8766 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8767 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 8768 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 8769 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8770 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8771 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 8772 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
f5fcc13c 8773 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 8774 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 8775
ac3e3741 8776 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8777 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8778 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
dea0a509 8779 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8780 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 8781 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 8782 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 8783 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 8784 ALC883_FUJITSU_PI2515),
bfb53037 8785 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 8786 ALC888_FUJITSU_XA3530),
272a527c 8787 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8788 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8789 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8790 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8791 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8792 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 8793 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 8794 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8795 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 8796
17bba1b7
J
8797 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8798 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 8799 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
8800 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8801 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8802 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
ac3e3741 8803 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e 8804
4953550a 8805 {}
f3cd3f5d
WF
8806};
8807
4953550a
TI
8808/* codec SSID table for Intel Mac */
8809static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8810 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8811 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8812 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8813 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8814 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8815 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8816 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8817 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8818 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8819 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8820 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8821 /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8822 * no perfect solution yet
8823 */
8824 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8825 {} /* terminator */
b25c9da1
WF
8826};
8827
4953550a
TI
8828static struct alc_config_preset alc882_presets[] = {
8829 [ALC882_3ST_DIG] = {
8830 .mixers = { alc882_base_mixer },
8ab9e0af
TI
8831 .init_verbs = { alc882_base_init_verbs,
8832 alc882_adc1_init_verbs },
4953550a
TI
8833 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8834 .dac_nids = alc882_dac_nids,
8835 .dig_out_nid = ALC882_DIGOUT_NID,
8836 .dig_in_nid = ALC882_DIGIN_NID,
8837 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8838 .channel_mode = alc882_ch_modes,
8839 .need_dac_fix = 1,
8840 .input_mux = &alc882_capture_source,
8841 },
8842 [ALC882_6ST_DIG] = {
8843 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
8844 .init_verbs = { alc882_base_init_verbs,
8845 alc882_adc1_init_verbs },
4953550a
TI
8846 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8847 .dac_nids = alc882_dac_nids,
8848 .dig_out_nid = ALC882_DIGOUT_NID,
8849 .dig_in_nid = ALC882_DIGIN_NID,
8850 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8851 .channel_mode = alc882_sixstack_modes,
8852 .input_mux = &alc882_capture_source,
8853 },
8854 [ALC882_ARIMA] = {
8855 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
8856 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8857 alc882_eapd_verbs },
4953550a
TI
8858 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8859 .dac_nids = alc882_dac_nids,
8860 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8861 .channel_mode = alc882_sixstack_modes,
8862 .input_mux = &alc882_capture_source,
8863 },
8864 [ALC882_W2JC] = {
8865 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
8866 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8867 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
8868 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8869 .dac_nids = alc882_dac_nids,
8870 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8871 .channel_mode = alc880_threestack_modes,
8872 .need_dac_fix = 1,
8873 .input_mux = &alc882_capture_source,
8874 .dig_out_nid = ALC882_DIGOUT_NID,
8875 },
8876 [ALC885_MBP3] = {
8877 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8878 .init_verbs = { alc885_mbp3_init_verbs,
8879 alc880_gpio1_init_verbs },
be0ae923 8880 .num_dacs = 2,
4953550a 8881 .dac_nids = alc882_dac_nids,
be0ae923
TI
8882 .hp_nid = 0x04,
8883 .channel_mode = alc885_mbp_4ch_modes,
8884 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
8885 .input_mux = &alc882_capture_source,
8886 .dig_out_nid = ALC882_DIGOUT_NID,
8887 .dig_in_nid = ALC882_DIGIN_NID,
8888 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
8889 .setup = alc885_mbp3_setup,
8890 .init_hook = alc_automute_amp,
4953550a
TI
8891 },
8892 [ALC885_MB5] = {
8893 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8894 .init_verbs = { alc885_mb5_init_verbs,
8895 alc880_gpio1_init_verbs },
8896 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8897 .dac_nids = alc882_dac_nids,
8898 .channel_mode = alc885_mb5_6ch_modes,
8899 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8900 .input_mux = &mb5_capture_source,
8901 .dig_out_nid = ALC882_DIGOUT_NID,
8902 .dig_in_nid = ALC882_DIGIN_NID,
8903 },
8904 [ALC885_MACPRO] = {
8905 .mixers = { alc882_macpro_mixer },
8906 .init_verbs = { alc882_macpro_init_verbs },
8907 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8908 .dac_nids = alc882_dac_nids,
8909 .dig_out_nid = ALC882_DIGOUT_NID,
8910 .dig_in_nid = ALC882_DIGIN_NID,
8911 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8912 .channel_mode = alc882_ch_modes,
8913 .input_mux = &alc882_capture_source,
8914 .init_hook = alc885_macpro_init_hook,
8915 },
8916 [ALC885_IMAC24] = {
8917 .mixers = { alc885_imac24_mixer },
8918 .init_verbs = { alc885_imac24_init_verbs },
8919 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8920 .dac_nids = alc882_dac_nids,
8921 .dig_out_nid = ALC882_DIGOUT_NID,
8922 .dig_in_nid = ALC882_DIGIN_NID,
8923 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8924 .channel_mode = alc882_ch_modes,
8925 .input_mux = &alc882_capture_source,
8926 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 8927 .setup = alc885_imac24_setup,
4953550a
TI
8928 .init_hook = alc885_imac24_init_hook,
8929 },
8930 [ALC882_TARGA] = {
8931 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 8932 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 8933 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
8934 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8935 .dac_nids = alc882_dac_nids,
8936 .dig_out_nid = ALC882_DIGOUT_NID,
8937 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8938 .adc_nids = alc882_adc_nids,
8939 .capsrc_nids = alc882_capsrc_nids,
8940 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8941 .channel_mode = alc882_3ST_6ch_modes,
8942 .need_dac_fix = 1,
8943 .input_mux = &alc882_capture_source,
8944 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
8945 .setup = alc882_targa_setup,
8946 .init_hook = alc882_targa_automute,
4953550a
TI
8947 },
8948 [ALC882_ASUS_A7J] = {
8949 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
8950 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8951 alc882_asus_a7j_verbs},
4953550a
TI
8952 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8953 .dac_nids = alc882_dac_nids,
8954 .dig_out_nid = ALC882_DIGOUT_NID,
8955 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8956 .adc_nids = alc882_adc_nids,
8957 .capsrc_nids = alc882_capsrc_nids,
8958 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8959 .channel_mode = alc882_3ST_6ch_modes,
8960 .need_dac_fix = 1,
8961 .input_mux = &alc882_capture_source,
8962 },
8963 [ALC882_ASUS_A7M] = {
8964 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
8965 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8966 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
8967 alc882_asus_a7m_verbs },
8968 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8969 .dac_nids = alc882_dac_nids,
8970 .dig_out_nid = ALC882_DIGOUT_NID,
8971 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8972 .channel_mode = alc880_threestack_modes,
8973 .need_dac_fix = 1,
8974 .input_mux = &alc882_capture_source,
8975 },
9c7f852e
TI
8976 [ALC883_3ST_2ch_DIG] = {
8977 .mixers = { alc883_3ST_2ch_mixer },
8978 .init_verbs = { alc883_init_verbs },
8979 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8980 .dac_nids = alc883_dac_nids,
8981 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8982 .dig_in_nid = ALC883_DIGIN_NID,
8983 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8984 .channel_mode = alc883_3ST_2ch_modes,
8985 .input_mux = &alc883_capture_source,
8986 },
8987 [ALC883_3ST_6ch_DIG] = {
8988 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8989 .init_verbs = { alc883_init_verbs },
8990 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8991 .dac_nids = alc883_dac_nids,
8992 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8993 .dig_in_nid = ALC883_DIGIN_NID,
8994 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8995 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8996 .need_dac_fix = 1,
9c7f852e 8997 .input_mux = &alc883_capture_source,
f12ab1e0 8998 },
9c7f852e
TI
8999 [ALC883_3ST_6ch] = {
9000 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9001 .init_verbs = { alc883_init_verbs },
9002 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9003 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9004 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9005 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9006 .need_dac_fix = 1,
9c7f852e 9007 .input_mux = &alc883_capture_source,
f12ab1e0 9008 },
17bba1b7
J
9009 [ALC883_3ST_6ch_INTEL] = {
9010 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9011 .init_verbs = { alc883_init_verbs },
9012 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9013 .dac_nids = alc883_dac_nids,
9014 .dig_out_nid = ALC883_DIGOUT_NID,
9015 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9016 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9017 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9018 .channel_mode = alc883_3ST_6ch_intel_modes,
9019 .need_dac_fix = 1,
9020 .input_mux = &alc883_3stack_6ch_intel,
9021 },
87a8c370
JK
9022 [ALC889A_INTEL] = {
9023 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9024 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9025 alc_hp15_unsol_verbs },
87a8c370
JK
9026 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9027 .dac_nids = alc883_dac_nids,
9028 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9029 .adc_nids = alc889_adc_nids,
9030 .dig_out_nid = ALC883_DIGOUT_NID,
9031 .dig_in_nid = ALC883_DIGIN_NID,
9032 .slave_dig_outs = alc883_slave_dig_outs,
9033 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9034 .channel_mode = alc889_8ch_intel_modes,
9035 .capsrc_nids = alc889_capsrc_nids,
9036 .input_mux = &alc889_capture_source,
4f5d1706
TI
9037 .setup = alc889_automute_setup,
9038 .init_hook = alc_automute_amp,
6732bd0d 9039 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9040 .need_dac_fix = 1,
9041 },
9042 [ALC889_INTEL] = {
9043 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9044 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9045 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9046 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9047 .dac_nids = alc883_dac_nids,
9048 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9049 .adc_nids = alc889_adc_nids,
9050 .dig_out_nid = ALC883_DIGOUT_NID,
9051 .dig_in_nid = ALC883_DIGIN_NID,
9052 .slave_dig_outs = alc883_slave_dig_outs,
9053 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9054 .channel_mode = alc889_8ch_intel_modes,
9055 .capsrc_nids = alc889_capsrc_nids,
9056 .input_mux = &alc889_capture_source,
4f5d1706 9057 .setup = alc889_automute_setup,
6732bd0d
WF
9058 .init_hook = alc889_intel_init_hook,
9059 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9060 .need_dac_fix = 1,
9061 },
9c7f852e
TI
9062 [ALC883_6ST_DIG] = {
9063 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9064 .init_verbs = { alc883_init_verbs },
9065 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9066 .dac_nids = alc883_dac_nids,
9067 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9068 .dig_in_nid = ALC883_DIGIN_NID,
9069 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9070 .channel_mode = alc883_sixstack_modes,
9071 .input_mux = &alc883_capture_source,
9072 },
ccc656ce 9073 [ALC883_TARGA_DIG] = {
c259249f 9074 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9075 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9076 alc883_targa_verbs},
ccc656ce
KY
9077 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9078 .dac_nids = alc883_dac_nids,
9079 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9080 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9081 .channel_mode = alc883_3ST_6ch_modes,
9082 .need_dac_fix = 1,
9083 .input_mux = &alc883_capture_source,
c259249f 9084 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9085 .setup = alc882_targa_setup,
9086 .init_hook = alc882_targa_automute,
ccc656ce
KY
9087 },
9088 [ALC883_TARGA_2ch_DIG] = {
c259249f 9089 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9090 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9091 alc883_targa_verbs},
ccc656ce
KY
9092 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9093 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9094 .adc_nids = alc883_adc_nids_alt,
9095 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
ccc656ce 9096 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9097 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9098 .channel_mode = alc883_3ST_2ch_modes,
9099 .input_mux = &alc883_capture_source,
c259249f 9100 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9101 .setup = alc882_targa_setup,
9102 .init_hook = alc882_targa_automute,
ccc656ce 9103 },
64a8be74
DH
9104 [ALC883_TARGA_8ch_DIG] = {
9105 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9106 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9107 alc883_targa_verbs },
64a8be74
DH
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 .dig_in_nid = ALC883_DIGIN_NID,
9115 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9116 .channel_mode = alc883_4ST_8ch_modes,
9117 .need_dac_fix = 1,
9118 .input_mux = &alc883_capture_source,
c259249f 9119 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9120 .setup = alc882_targa_setup,
9121 .init_hook = alc882_targa_automute,
64a8be74 9122 },
bab282b9 9123 [ALC883_ACER] = {
676a9b53 9124 .mixers = { alc883_base_mixer },
bab282b9
VA
9125 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9126 * and the headphone jack. Turn this on and rely on the
9127 * standard mute methods whenever the user wants to turn
9128 * these outputs off.
9129 */
9130 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9131 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9132 .dac_nids = alc883_dac_nids,
bab282b9
VA
9133 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9134 .channel_mode = alc883_3ST_2ch_modes,
9135 .input_mux = &alc883_capture_source,
9136 },
2880a867 9137 [ALC883_ACER_ASPIRE] = {
676a9b53 9138 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 9139 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
9140 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9141 .dac_nids = alc883_dac_nids,
9142 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
9143 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9144 .channel_mode = alc883_3ST_2ch_modes,
9145 .input_mux = &alc883_capture_source,
a9fd4f3f 9146 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9147 .setup = alc883_acer_aspire_setup,
9148 .init_hook = alc_automute_amp,
d1a991a6 9149 },
5b2d1eca 9150 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 9151 .mixers = { alc888_base_mixer,
5b2d1eca
VP
9152 alc883_chmode_mixer },
9153 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9154 alc888_acer_aspire_4930g_verbs },
9155 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9156 .dac_nids = alc883_dac_nids,
9157 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9158 .adc_nids = alc883_adc_nids_rev,
9159 .capsrc_nids = alc883_capsrc_nids_rev,
9160 .dig_out_nid = ALC883_DIGOUT_NID,
9161 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9162 .channel_mode = alc883_3ST_6ch_modes,
9163 .need_dac_fix = 1,
9164 .num_mux_defs =
ef8ef5fb
VP
9165 ARRAY_SIZE(alc888_2_capture_sources),
9166 .input_mux = alc888_2_capture_sources,
d2fd4b09 9167 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9168 .setup = alc888_acer_aspire_4930g_setup,
9169 .init_hook = alc_automute_amp,
d2fd4b09
TV
9170 },
9171 [ALC888_ACER_ASPIRE_6530G] = {
9172 .mixers = { alc888_acer_aspire_6530_mixer },
9173 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9174 alc888_acer_aspire_6530g_verbs },
9175 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9176 .dac_nids = alc883_dac_nids,
9177 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9178 .adc_nids = alc883_adc_nids_rev,
9179 .capsrc_nids = alc883_capsrc_nids_rev,
9180 .dig_out_nid = ALC883_DIGOUT_NID,
9181 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9182 .channel_mode = alc883_3ST_2ch_modes,
9183 .num_mux_defs =
9184 ARRAY_SIZE(alc888_2_capture_sources),
9185 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 9186 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9187 .setup = alc888_acer_aspire_6530g_setup,
9188 .init_hook = alc_automute_amp,
5b2d1eca 9189 },
3b315d70
HM
9190 [ALC888_ACER_ASPIRE_8930G] = {
9191 .mixers = { alc888_base_mixer,
9192 alc883_chmode_mixer },
9193 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
018df418 9194 alc889_acer_aspire_8930g_verbs },
3b315d70
HM
9195 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9196 .dac_nids = alc883_dac_nids,
018df418
HM
9197 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9198 .adc_nids = alc889_adc_nids,
9199 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
9200 .dig_out_nid = ALC883_DIGOUT_NID,
9201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9202 .channel_mode = alc883_3ST_6ch_modes,
9203 .need_dac_fix = 1,
9204 .const_channel_count = 6,
9205 .num_mux_defs =
018df418
HM
9206 ARRAY_SIZE(alc889_capture_sources),
9207 .input_mux = alc889_capture_sources,
3b315d70 9208 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9209 .setup = alc889_acer_aspire_8930g_setup,
9210 .init_hook = alc_automute_amp,
3b315d70 9211 },
fc86f954
DK
9212 [ALC888_ACER_ASPIRE_7730G] = {
9213 .mixers = { alc883_3ST_6ch_mixer,
9214 alc883_chmode_mixer },
9215 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9216 alc888_acer_aspire_7730G_verbs },
9217 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9218 .dac_nids = alc883_dac_nids,
9219 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9220 .adc_nids = alc883_adc_nids_rev,
9221 .capsrc_nids = alc883_capsrc_nids_rev,
9222 .dig_out_nid = ALC883_DIGOUT_NID,
9223 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9224 .channel_mode = alc883_3ST_6ch_modes,
9225 .need_dac_fix = 1,
9226 .const_channel_count = 6,
9227 .input_mux = &alc883_capture_source,
9228 .unsol_event = alc_automute_amp_unsol_event,
9229 .setup = alc888_acer_aspire_6530g_setup,
9230 .init_hook = alc_automute_amp,
9231 },
c07584c8
TD
9232 [ALC883_MEDION] = {
9233 .mixers = { alc883_fivestack_mixer,
9234 alc883_chmode_mixer },
9235 .init_verbs = { alc883_init_verbs,
b373bdeb 9236 alc883_medion_eapd_verbs },
c07584c8
TD
9237 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9238 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9239 .adc_nids = alc883_adc_nids_alt,
9240 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
c07584c8
TD
9241 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9242 .channel_mode = alc883_sixstack_modes,
9243 .input_mux = &alc883_capture_source,
b373bdeb 9244 },
272a527c
KY
9245 [ALC883_MEDION_MD2] = {
9246 .mixers = { alc883_medion_md2_mixer},
9247 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9248 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9249 .dac_nids = alc883_dac_nids,
9250 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9251 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9252 .channel_mode = alc883_3ST_2ch_modes,
9253 .input_mux = &alc883_capture_source,
a9fd4f3f 9254 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9255 .setup = alc883_medion_md2_setup,
9256 .init_hook = alc_automute_amp,
ea1fb29a 9257 },
b373bdeb 9258 [ALC883_LAPTOP_EAPD] = {
676a9b53 9259 .mixers = { alc883_base_mixer },
b373bdeb
AN
9260 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9261 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9262 .dac_nids = alc883_dac_nids,
b373bdeb
AN
9263 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9264 .channel_mode = alc883_3ST_2ch_modes,
9265 .input_mux = &alc883_capture_source,
9266 },
0c4cc443
HRK
9267 [ALC883_CLEVO_M720] = {
9268 .mixers = { alc883_clevo_m720_mixer },
9269 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
9270 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9271 .dac_nids = alc883_dac_nids,
9272 .dig_out_nid = ALC883_DIGOUT_NID,
9273 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9274 .channel_mode = alc883_3ST_2ch_modes,
9275 .input_mux = &alc883_capture_source,
0c4cc443 9276 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 9277 .setup = alc883_clevo_m720_setup,
a9fd4f3f 9278 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 9279 },
bc9f98a9
KY
9280 [ALC883_LENOVO_101E_2ch] = {
9281 .mixers = { alc883_lenovo_101e_2ch_mixer},
9282 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9283 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9284 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9285 .adc_nids = alc883_adc_nids_alt,
9286 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
bc9f98a9
KY
9287 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9288 .channel_mode = alc883_3ST_2ch_modes,
9289 .input_mux = &alc883_lenovo_101e_capture_source,
9290 .unsol_event = alc883_lenovo_101e_unsol_event,
9291 .init_hook = alc883_lenovo_101e_all_automute,
9292 },
272a527c
KY
9293 [ALC883_LENOVO_NB0763] = {
9294 .mixers = { alc883_lenovo_nb0763_mixer },
9295 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9296 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9297 .dac_nids = alc883_dac_nids,
272a527c
KY
9298 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9299 .channel_mode = alc883_3ST_2ch_modes,
9300 .need_dac_fix = 1,
9301 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 9302 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9303 .setup = alc883_medion_md2_setup,
9304 .init_hook = alc_automute_amp,
272a527c
KY
9305 },
9306 [ALC888_LENOVO_MS7195_DIG] = {
9307 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9308 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9309 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9310 .dac_nids = alc883_dac_nids,
9311 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9312 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9313 .channel_mode = alc883_3ST_6ch_modes,
9314 .need_dac_fix = 1,
9315 .input_mux = &alc883_capture_source,
9316 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9317 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
9318 },
9319 [ALC883_HAIER_W66] = {
c259249f 9320 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
9321 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9322 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9323 .dac_nids = alc883_dac_nids,
9324 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
9325 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9326 .channel_mode = alc883_3ST_2ch_modes,
9327 .input_mux = &alc883_capture_source,
a9fd4f3f 9328 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9329 .setup = alc883_haier_w66_setup,
9330 .init_hook = alc_automute_amp,
eea6419e 9331 },
4723c022 9332 [ALC888_3ST_HP] = {
eea6419e 9333 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 9334 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
9335 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9336 .dac_nids = alc883_dac_nids,
4723c022
CM
9337 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9338 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
9339 .need_dac_fix = 1,
9340 .input_mux = &alc883_capture_source,
a9fd4f3f 9341 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9342 .setup = alc888_3st_hp_setup,
9343 .init_hook = alc_automute_amp,
8341de60 9344 },
5795b9e6 9345 [ALC888_6ST_DELL] = {
f24dbdc6 9346 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
9347 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9348 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9349 .dac_nids = alc883_dac_nids,
9350 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
9351 .dig_in_nid = ALC883_DIGIN_NID,
9352 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9353 .channel_mode = alc883_sixstack_modes,
9354 .input_mux = &alc883_capture_source,
a9fd4f3f 9355 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9356 .setup = alc888_6st_dell_setup,
9357 .init_hook = alc_automute_amp,
5795b9e6 9358 },
a8848bd6
AS
9359 [ALC883_MITAC] = {
9360 .mixers = { alc883_mitac_mixer },
9361 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9362 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9363 .dac_nids = alc883_dac_nids,
a8848bd6
AS
9364 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9365 .channel_mode = alc883_3ST_2ch_modes,
9366 .input_mux = &alc883_capture_source,
a9fd4f3f 9367 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9368 .setup = alc883_mitac_setup,
9369 .init_hook = alc_automute_amp,
a8848bd6 9370 },
fb97dc67
J
9371 [ALC883_FUJITSU_PI2515] = {
9372 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9373 .init_verbs = { alc883_init_verbs,
9374 alc883_2ch_fujitsu_pi2515_verbs},
9375 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9376 .dac_nids = alc883_dac_nids,
9377 .dig_out_nid = ALC883_DIGOUT_NID,
9378 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9379 .channel_mode = alc883_3ST_2ch_modes,
9380 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 9381 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9382 .setup = alc883_2ch_fujitsu_pi2515_setup,
9383 .init_hook = alc_automute_amp,
fb97dc67 9384 },
ef8ef5fb
VP
9385 [ALC888_FUJITSU_XA3530] = {
9386 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9387 .init_verbs = { alc883_init_verbs,
9388 alc888_fujitsu_xa3530_verbs },
9389 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9390 .dac_nids = alc883_dac_nids,
9391 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9392 .adc_nids = alc883_adc_nids_rev,
9393 .capsrc_nids = alc883_capsrc_nids_rev,
9394 .dig_out_nid = ALC883_DIGOUT_NID,
9395 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9396 .channel_mode = alc888_4ST_8ch_intel_modes,
9397 .num_mux_defs =
9398 ARRAY_SIZE(alc888_2_capture_sources),
9399 .input_mux = alc888_2_capture_sources,
a9fd4f3f 9400 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9401 .setup = alc888_fujitsu_xa3530_setup,
9402 .init_hook = alc_automute_amp,
ef8ef5fb 9403 },
e2757d5e
KY
9404 [ALC888_LENOVO_SKY] = {
9405 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9406 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9407 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9408 .dac_nids = alc883_dac_nids,
9409 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
9410 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9411 .channel_mode = alc883_sixstack_modes,
9412 .need_dac_fix = 1,
9413 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 9414 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9415 .setup = alc888_lenovo_sky_setup,
9416 .init_hook = alc_automute_amp,
e2757d5e
KY
9417 },
9418 [ALC888_ASUS_M90V] = {
9419 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9420 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9421 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9422 .dac_nids = alc883_dac_nids,
9423 .dig_out_nid = ALC883_DIGOUT_NID,
9424 .dig_in_nid = ALC883_DIGIN_NID,
9425 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9426 .channel_mode = alc883_3ST_6ch_modes,
9427 .need_dac_fix = 1,
9428 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
9429 .unsol_event = alc_sku_unsol_event,
9430 .setup = alc883_mode2_setup,
9431 .init_hook = alc_inithook,
e2757d5e
KY
9432 },
9433 [ALC888_ASUS_EEE1601] = {
9434 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 9435 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
9436 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9437 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9438 .dac_nids = alc883_dac_nids,
9439 .dig_out_nid = ALC883_DIGOUT_NID,
9440 .dig_in_nid = ALC883_DIGIN_NID,
9441 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9442 .channel_mode = alc883_3ST_2ch_modes,
9443 .need_dac_fix = 1,
9444 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 9445 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
9446 .init_hook = alc883_eee1601_inithook,
9447 },
3ab90935
WF
9448 [ALC1200_ASUS_P5Q] = {
9449 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9450 .init_verbs = { alc883_init_verbs },
9451 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9452 .dac_nids = alc883_dac_nids,
9453 .dig_out_nid = ALC1200_DIGOUT_NID,
9454 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 9455 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
9456 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9457 .channel_mode = alc883_sixstack_modes,
9458 .input_mux = &alc883_capture_source,
9459 },
eb4c41d3
TS
9460 [ALC889A_MB31] = {
9461 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9462 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9463 alc880_gpio1_init_verbs },
9464 .adc_nids = alc883_adc_nids,
9465 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9466 .dac_nids = alc883_dac_nids,
9467 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9468 .channel_mode = alc889A_mb31_6ch_modes,
9469 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9470 .input_mux = &alc889A_mb31_capture_source,
9471 .dig_out_nid = ALC883_DIGOUT_NID,
9472 .unsol_event = alc889A_mb31_unsol_event,
9473 .init_hook = alc889A_mb31_automute,
9474 },
3e1647c5
GG
9475 [ALC883_SONY_VAIO_TT] = {
9476 .mixers = { alc883_vaiott_mixer },
9477 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9479 .dac_nids = alc883_dac_nids,
9480 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9481 .channel_mode = alc883_3ST_2ch_modes,
9482 .input_mux = &alc883_capture_source,
9483 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9484 .setup = alc883_vaiott_setup,
9485 .init_hook = alc_automute_amp,
3e1647c5 9486 },
9c7f852e
TI
9487};
9488
9489
4953550a
TI
9490/*
9491 * Pin config fixes
9492 */
9493enum {
9494 PINFIX_ABIT_AW9D_MAX
9495};
9496
9497static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9498 { 0x15, 0x01080104 }, /* side */
9499 { 0x16, 0x01011012 }, /* rear */
9500 { 0x17, 0x01016011 }, /* clfe */
9501 { }
9502};
9503
9504static const struct alc_pincfg *alc882_pin_fixes[] = {
9505 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9506};
9507
9508static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9509 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9510 {}
9511};
9512
9c7f852e
TI
9513/*
9514 * BIOS auto configuration
9515 */
05f5f477
TI
9516static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9517 const struct auto_pin_cfg *cfg)
9518{
9519 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9520}
9521
4953550a 9522static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e
TI
9523 hda_nid_t nid, int pin_type,
9524 int dac_idx)
9525{
9526 /* set as output */
9527 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
9528 int idx;
9529
f6c7e546 9530 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
9531 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9532 idx = 4;
9533 else
9534 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
9535 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9536
9537}
9538
4953550a 9539static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
9540{
9541 struct alc_spec *spec = codec->spec;
9542 int i;
9543
9544 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 9545 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 9546 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 9547 if (nid)
4953550a 9548 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 9549 i);
9c7f852e
TI
9550 }
9551}
9552
4953550a 9553static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
9554{
9555 struct alc_spec *spec = codec->spec;
9556 hda_nid_t pin;
9557
eb06ed8f 9558 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
9559 if (pin) /* connect to front */
9560 /* use dac 0 */
4953550a 9561 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
9562 pin = spec->autocfg.speaker_pins[0];
9563 if (pin)
4953550a 9564 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
9565}
9566
4953550a 9567static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
9568{
9569 struct alc_spec *spec = codec->spec;
9570 int i;
9571
9572 for (i = 0; i < AUTO_PIN_LAST; i++) {
9573 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
9574 if (!nid)
9575 continue;
0d971c9f 9576 alc_set_input_pin(codec, nid, i);
4953550a
TI
9577 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9578 snd_hda_codec_write(codec, nid, 0,
9579 AC_VERB_SET_AMP_GAIN_MUTE,
9580 AMP_OUT_MUTE);
9581 }
9582}
9583
9584static void alc882_auto_init_input_src(struct hda_codec *codec)
9585{
9586 struct alc_spec *spec = codec->spec;
9587 int c;
9588
9589 for (c = 0; c < spec->num_adc_nids; c++) {
9590 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9591 hda_nid_t nid = spec->capsrc_nids[c];
9592 unsigned int mux_idx;
9593 const struct hda_input_mux *imux;
9594 int conns, mute, idx, item;
9595
9596 conns = snd_hda_get_connections(codec, nid, conn_list,
9597 ARRAY_SIZE(conn_list));
9598 if (conns < 0)
9599 continue;
9600 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9601 imux = &spec->input_mux[mux_idx];
9602 for (idx = 0; idx < conns; idx++) {
9603 /* if the current connection is the selected one,
9604 * unmute it as default - otherwise mute it
9605 */
9606 mute = AMP_IN_MUTE(idx);
9607 for (item = 0; item < imux->num_items; item++) {
9608 if (imux->items[item].index == idx) {
9609 if (spec->cur_mux[c] == item)
9610 mute = AMP_IN_UNMUTE(idx);
9611 break;
9612 }
9613 }
9614 /* check if we have a selector or mixer
9615 * we could check for the widget type instead, but
9616 * just check for Amp-In presence (in case of mixer
9617 * without amp-in there is something wrong, this
9618 * function shouldn't be used or capsrc nid is wrong)
9619 */
9620 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
9621 snd_hda_codec_write(codec, nid, 0,
9622 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
9623 mute);
9624 else if (mute != AMP_IN_MUTE(idx))
9625 snd_hda_codec_write(codec, nid, 0,
9626 AC_VERB_SET_CONNECT_SEL,
9627 idx);
9c7f852e
TI
9628 }
9629 }
9630}
9631
4953550a
TI
9632/* add mic boosts if needed */
9633static int alc_auto_add_mic_boost(struct hda_codec *codec)
9634{
9635 struct alc_spec *spec = codec->spec;
9636 int err;
9637 hda_nid_t nid;
9638
9639 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9640 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9641 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9642 "Mic Boost",
9643 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9644 if (err < 0)
9645 return err;
9646 }
9647 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9648 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9649 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9650 "Front Mic Boost",
9651 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9652 if (err < 0)
9653 return err;
9654 }
9655 return 0;
9656}
f511b01c 9657
9c7f852e 9658/* almost identical with ALC880 parser... */
4953550a 9659static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
9660{
9661 struct alc_spec *spec = codec->spec;
05f5f477
TI
9662 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
9663 int i, err;
9c7f852e 9664
05f5f477
TI
9665 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9666 alc882_ignore);
9c7f852e
TI
9667 if (err < 0)
9668 return err;
05f5f477
TI
9669 if (!spec->autocfg.line_outs)
9670 return 0; /* can't find valid BIOS pin config */
776e184e 9671
05f5f477
TI
9672 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9673 if (err < 0)
9674 return err;
9675 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
9676 if (err < 0)
9677 return err;
9678 err = alc880_auto_create_extra_out(spec,
9679 spec->autocfg.speaker_pins[0],
9680 "Speaker");
9681 if (err < 0)
9682 return err;
9683 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
9684 "Headphone");
9685 if (err < 0)
9686 return err;
9687 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
9688 if (err < 0)
9689 return err;
9690
05f5f477
TI
9691 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9692
9693 /* check multiple SPDIF-out (for recent codecs) */
9694 for (i = 0; i < spec->autocfg.dig_outs; i++) {
9695 hda_nid_t dig_nid;
9696 err = snd_hda_get_connections(codec,
9697 spec->autocfg.dig_out_pins[i],
9698 &dig_nid, 1);
9699 if (err < 0)
9700 continue;
9701 if (!i)
9702 spec->multiout.dig_out_nid = dig_nid;
9703 else {
9704 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9705 spec->slave_dig_outs[i - 1] = dig_nid;
9706 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
9707 break;
9708 }
9709 }
9710 if (spec->autocfg.dig_in_pin)
9711 spec->dig_in_nid = ALC880_DIGIN_NID;
9712
9713 if (spec->kctls.list)
9714 add_mixer(spec, spec->kctls.list);
9715
9716 add_verb(spec, alc883_auto_init_verbs);
4953550a 9717 /* if ADC 0x07 is available, initialize it, too */
05f5f477 9718 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 9719 add_verb(spec, alc882_adc1_init_verbs);
776e184e 9720
05f5f477
TI
9721 spec->num_mux_defs = 1;
9722 spec->input_mux = &spec->private_imux[0];
9723
9724 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
9725
9726 err = alc_auto_add_mic_boost(codec);
9727 if (err < 0)
9728 return err;
61b9b9b1 9729
776e184e 9730 return 1; /* config found */
9c7f852e
TI
9731}
9732
9733/* additional initialization for auto-configuration model */
4953550a 9734static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 9735{
f6c7e546 9736 struct alc_spec *spec = codec->spec;
4953550a
TI
9737 alc882_auto_init_multi_out(codec);
9738 alc882_auto_init_hp_out(codec);
9739 alc882_auto_init_analog_input(codec);
9740 alc882_auto_init_input_src(codec);
f6c7e546 9741 if (spec->unsol_event)
7fb0d78f 9742 alc_inithook(codec);
9c7f852e
TI
9743}
9744
4953550a 9745static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
9746{
9747 struct alc_spec *spec;
9748 int err, board_config;
9749
9750 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9751 if (spec == NULL)
9752 return -ENOMEM;
9753
9754 codec->spec = spec;
9755
4953550a
TI
9756 switch (codec->vendor_id) {
9757 case 0x10ec0882:
9758 case 0x10ec0885:
9759 break;
9760 default:
9761 /* ALC883 and variants */
9762 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9763 break;
9764 }
2c3bf9ab 9765
4953550a
TI
9766 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9767 alc882_models,
9768 alc882_cfg_tbl);
9769
9770 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9771 board_config = snd_hda_check_board_codec_sid_config(codec,
9772 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9773
9774 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 9775 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
9776 codec->chip_name);
9777 board_config = ALC882_AUTO;
9c7f852e
TI
9778 }
9779
4953550a
TI
9780 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9781
9782 if (board_config == ALC882_AUTO) {
9c7f852e 9783 /* automatic parse from the BIOS config */
4953550a 9784 err = alc882_parse_auto_config(codec);
9c7f852e
TI
9785 if (err < 0) {
9786 alc_free(codec);
9787 return err;
f12ab1e0 9788 } else if (!err) {
9c7f852e
TI
9789 printk(KERN_INFO
9790 "hda_codec: Cannot set up configuration "
9791 "from BIOS. Using base mode...\n");
4953550a 9792 board_config = ALC882_3ST_DIG;
9c7f852e
TI
9793 }
9794 }
9795
680cd536
KK
9796 err = snd_hda_attach_beep_device(codec, 0x1);
9797 if (err < 0) {
9798 alc_free(codec);
9799 return err;
9800 }
9801
4953550a 9802 if (board_config != ALC882_AUTO)
e9c364c0 9803 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 9804
4953550a
TI
9805 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9806 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9807 /* FIXME: setup DAC5 */
9808 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9809 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9810
9811 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9812 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9813
9814 if (codec->vendor_id == 0x10ec0888)
4a79ba34 9815 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
4953550a
TI
9816
9817 if (!spec->adc_nids && spec->input_mux) {
9818 int i;
9819 spec->num_adc_nids = 0;
9820 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9821 hda_nid_t cap;
9822 hda_nid_t nid = alc882_adc_nids[i];
9823 unsigned int wcap = get_wcaps(codec, nid);
9824 /* get type */
a22d543a 9825 wcap = get_wcaps_type(wcap);
4953550a
TI
9826 if (wcap != AC_WID_AUD_IN)
9827 continue;
9828 spec->private_adc_nids[spec->num_adc_nids] = nid;
9829 err = snd_hda_get_connections(codec, nid, &cap, 1);
9830 if (err < 0)
9831 continue;
9832 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9833 spec->num_adc_nids++;
61b9b9b1 9834 }
4953550a
TI
9835 spec->adc_nids = spec->private_adc_nids;
9836 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
9837 }
9838
b59bdf3b 9839 set_capture_mixer(codec);
45bdd1c1 9840 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 9841
2134ea4f
TI
9842 spec->vmaster_nid = 0x0c;
9843
9c7f852e 9844 codec->patch_ops = alc_patch_ops;
4953550a
TI
9845 if (board_config == ALC882_AUTO)
9846 spec->init_hook = alc882_auto_init;
cb53c626
TI
9847#ifdef CONFIG_SND_HDA_POWER_SAVE
9848 if (!spec->loopback.amplist)
4953550a 9849 spec->loopback.amplist = alc882_loopbacks;
cb53c626 9850#endif
daead538 9851 codec->proc_widget_hook = print_realtek_coef;
9c7f852e
TI
9852
9853 return 0;
9854}
9855
4953550a 9856
9c7f852e
TI
9857/*
9858 * ALC262 support
9859 */
9860
9861#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9862#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9863
9864#define alc262_dac_nids alc260_dac_nids
9865#define alc262_adc_nids alc882_adc_nids
9866#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
9867#define alc262_capsrc_nids alc882_capsrc_nids
9868#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
9869
9870#define alc262_modes alc260_modes
9871#define alc262_capture_source alc882_capture_source
9872
4e555fe5
KY
9873static hda_nid_t alc262_dmic_adc_nids[1] = {
9874 /* ADC0 */
9875 0x09
9876};
9877
9878static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9879
9c7f852e
TI
9880static struct snd_kcontrol_new alc262_base_mixer[] = {
9881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9882 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9883 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9884 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9887 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9888 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9889 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9890 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9891 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9892 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9893 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9894 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9895 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9896 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9897 { } /* end */
9898};
9899
ce875f07
TI
9900/* update HP, line and mono-out pins according to the master switch */
9901static void alc262_hp_master_update(struct hda_codec *codec)
9902{
9903 struct alc_spec *spec = codec->spec;
9904 int val = spec->master_sw;
9905
9906 /* HP & line-out */
9907 snd_hda_codec_write_cache(codec, 0x1b, 0,
9908 AC_VERB_SET_PIN_WIDGET_CONTROL,
9909 val ? PIN_HP : 0);
9910 snd_hda_codec_write_cache(codec, 0x15, 0,
9911 AC_VERB_SET_PIN_WIDGET_CONTROL,
9912 val ? PIN_HP : 0);
9913 /* mono (speaker) depending on the HP jack sense */
9914 val = val && !spec->jack_present;
9915 snd_hda_codec_write_cache(codec, 0x16, 0,
9916 AC_VERB_SET_PIN_WIDGET_CONTROL,
9917 val ? PIN_OUT : 0);
9918}
9919
9920static void alc262_hp_bpc_automute(struct hda_codec *codec)
9921{
9922 struct alc_spec *spec = codec->spec;
9923 unsigned int presence;
9924 presence = snd_hda_codec_read(codec, 0x1b, 0,
9925 AC_VERB_GET_PIN_SENSE, 0);
9926 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9927 alc262_hp_master_update(codec);
9928}
9929
9930static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9931{
9932 if ((res >> 26) != ALC880_HP_EVENT)
9933 return;
9934 alc262_hp_bpc_automute(codec);
9935}
9936
9937static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9938{
9939 struct alc_spec *spec = codec->spec;
9940 unsigned int presence;
9941 presence = snd_hda_codec_read(codec, 0x15, 0,
9942 AC_VERB_GET_PIN_SENSE, 0);
9943 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9944 alc262_hp_master_update(codec);
9945}
9946
9947static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9948 unsigned int res)
9949{
9950 if ((res >> 26) != ALC880_HP_EVENT)
9951 return;
9952 alc262_hp_wildwest_automute(codec);
9953}
9954
b72519b5 9955#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
9956
9957static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9958 struct snd_ctl_elem_value *ucontrol)
9959{
9960 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9961 struct alc_spec *spec = codec->spec;
9962 int val = !!*ucontrol->value.integer.value;
9963
9964 if (val == spec->master_sw)
9965 return 0;
9966 spec->master_sw = val;
9967 alc262_hp_master_update(codec);
9968 return 1;
9969}
9970
b72519b5
TI
9971#define ALC262_HP_MASTER_SWITCH \
9972 { \
9973 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9974 .name = "Master Playback Switch", \
9975 .info = snd_ctl_boolean_mono_info, \
9976 .get = alc262_hp_master_sw_get, \
9977 .put = alc262_hp_master_sw_put, \
9978 }
9979
9c7f852e 9980static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 9981 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
9982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9983 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9985 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9986 HDA_OUTPUT),
9987 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9988 HDA_OUTPUT),
9c7f852e
TI
9989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9991 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9992 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9993 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9994 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
9999 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10000 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10001 { } /* end */
10002};
10003
cd7509a4 10004static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10005 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10007 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10008 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10010 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10011 HDA_OUTPUT),
10012 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10013 HDA_OUTPUT),
cd7509a4
KY
10014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10016 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10019 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10020 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10021 { } /* end */
10022};
10023
10024static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10025 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10026 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10027 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10028 { } /* end */
10029};
10030
66d2a9d6 10031/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10032static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10033{
10034 struct alc_spec *spec = codec->spec;
66d2a9d6 10035
a9fd4f3f
TI
10036 spec->autocfg.hp_pins[0] = 0x15;
10037 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
66d2a9d6
KY
10038}
10039
66d2a9d6 10040static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10041 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10042 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10047 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10048 { } /* end */
10049};
10050
10051static struct hda_verb alc262_hp_t5735_verbs[] = {
10052 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10054
10055 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10056 { }
10057};
10058
8c427226 10059static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
10060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
10062 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10063 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
10064 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10065 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10066 { } /* end */
10067};
10068
10069static struct hda_verb alc262_hp_rp5700_verbs[] = {
10070 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10071 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10072 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10074 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10075 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10080 {}
10081};
10082
10083static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10084 .num_items = 1,
10085 .items = {
10086 { "Line", 0x1 },
10087 },
10088};
10089
42171c17
TI
10090/* bind hp and internal speaker mute (with plug check) as master switch */
10091static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 10092{
42171c17
TI
10093 struct alc_spec *spec = codec->spec;
10094 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10095 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10096 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10097 unsigned int mute;
0724ea2a 10098
42171c17
TI
10099 /* HP */
10100 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10101 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10102 HDA_AMP_MUTE, mute);
10103 /* mute internal speaker per jack sense */
10104 if (spec->jack_present)
10105 mute = HDA_AMP_MUTE;
10106 if (line_nid)
10107 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10108 HDA_AMP_MUTE, mute);
10109 if (speaker_nid && speaker_nid != line_nid)
10110 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 10111 HDA_AMP_MUTE, mute);
42171c17
TI
10112}
10113
10114#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10115
10116static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10117 struct snd_ctl_elem_value *ucontrol)
10118{
10119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10120 struct alc_spec *spec = codec->spec;
10121 int val = !!*ucontrol->value.integer.value;
10122
10123 if (val == spec->master_sw)
10124 return 0;
10125 spec->master_sw = val;
10126 alc262_hippo_master_update(codec);
10127 return 1;
10128}
10129
10130#define ALC262_HIPPO_MASTER_SWITCH \
10131 { \
10132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10133 .name = "Master Playback Switch", \
10134 .info = snd_ctl_boolean_mono_info, \
10135 .get = alc262_hippo_master_sw_get, \
10136 .put = alc262_hippo_master_sw_put, \
0724ea2a 10137 }
42171c17
TI
10138
10139static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10140 ALC262_HIPPO_MASTER_SWITCH,
10141 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10142 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10143 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10148 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10149 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10151 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10153 { } /* end */
10154};
10155
10156static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10157 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10158 ALC262_HIPPO_MASTER_SWITCH,
10159 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10160 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10161 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10162 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10163 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10164 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10165 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10166 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10167 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10168 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10169 { } /* end */
10170};
10171
10172/* mute/unmute internal speaker according to the hp jack and mute state */
10173static void alc262_hippo_automute(struct hda_codec *codec)
10174{
10175 struct alc_spec *spec = codec->spec;
10176 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10177 unsigned int present;
10178
10179 /* need to execute and sync at first */
10180 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
10181 present = snd_hda_codec_read(codec, hp_nid, 0,
10182 AC_VERB_GET_PIN_SENSE, 0);
10183 spec->jack_present = (present & 0x80000000) != 0;
10184 alc262_hippo_master_update(codec);
0724ea2a 10185}
5b31954e 10186
42171c17
TI
10187static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10188{
10189 if ((res >> 26) != ALC880_HP_EVENT)
10190 return;
10191 alc262_hippo_automute(codec);
10192}
10193
4f5d1706 10194static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
10195{
10196 struct alc_spec *spec = codec->spec;
10197
10198 spec->autocfg.hp_pins[0] = 0x15;
10199 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10200}
10201
4f5d1706 10202static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
10203{
10204 struct alc_spec *spec = codec->spec;
10205
10206 spec->autocfg.hp_pins[0] = 0x1b;
10207 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10208}
10209
10210
272a527c 10211static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 10212 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 10213 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
10214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10216 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10217 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10218 { } /* end */
10219};
10220
83c34218 10221static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
10222 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10223 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
10224 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10227 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10228 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10229 { } /* end */
10230};
272a527c 10231
ba340e82
TV
10232static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10233 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10234 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10235 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10236 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10237 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10238 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10241 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10242 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10243 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10244 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10245 { } /* end */
10246};
10247
10248static struct hda_verb alc262_tyan_verbs[] = {
10249 /* Headphone automute */
10250 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10251 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10252 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10253
10254 /* P11 AUX_IN, white 4-pin connector */
10255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10256 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10257 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10258 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10259
10260 {}
10261};
10262
10263/* unsolicited event for HP jack sensing */
4f5d1706 10264static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 10265{
a9fd4f3f 10266 struct alc_spec *spec = codec->spec;
ba340e82 10267
a9fd4f3f
TI
10268 spec->autocfg.hp_pins[0] = 0x1b;
10269 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
10270}
10271
ba340e82 10272
9c7f852e
TI
10273#define alc262_capture_mixer alc882_capture_mixer
10274#define alc262_capture_alt_mixer alc882_capture_alt_mixer
10275
10276/*
10277 * generic initialization of ADC, input mixers and output mixers
10278 */
10279static struct hda_verb alc262_init_verbs[] = {
10280 /*
10281 * Unmute ADC0-2 and set the default input to mic-in
10282 */
10283 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10285 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10287 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10289
cb53c626 10290 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10291 * mixer widget
f12ab1e0
TI
10292 * Note: PASD motherboards uses the Line In 2 as the input for
10293 * front panel mic (mic 2)
9c7f852e
TI
10294 */
10295 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
10301
10302 /*
df694daa
KY
10303 * Set up output mixers (0x0c - 0x0e)
10304 */
10305 /* set vol=0 to output mixers */
10306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10309 /* set up input amps for analog loopback */
10310 /* Amp Indices: DAC = 0, mixer = 1 */
10311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10315 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10317
10318 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10319 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10320 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10321 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10322 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10323 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10324
10325 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10327 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10328 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10329 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 10330
df694daa
KY
10331 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 10333
df694daa
KY
10334 /* FIXME: use matrix-type input source selection */
10335 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10336 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10337 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10338 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10339 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10340 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10341 /* Input mixer2 */
10342 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10343 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10344 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10345 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10346 /* Input mixer3 */
10347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10349 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 10350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
10351
10352 { }
10353};
1da177e4 10354
4e555fe5
KY
10355static struct hda_verb alc262_eapd_verbs[] = {
10356 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10357 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10358 { }
10359};
10360
ccc656ce
KY
10361static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10362 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10363 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10364 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10365
10366 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10368 {}
10369};
10370
272a527c
KY
10371static struct hda_verb alc262_sony_unsol_verbs[] = {
10372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10374 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10375
10376 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10377 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 10378 {}
272a527c
KY
10379};
10380
4e555fe5
KY
10381static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10382 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10383 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10385 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10386 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
10387 { } /* end */
10388};
10389
10390static struct hda_verb alc262_toshiba_s06_verbs[] = {
10391 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10392 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10394 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10395 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10396 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10397 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10398 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10399 {}
10400};
10401
4f5d1706 10402static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 10403{
a9fd4f3f
TI
10404 struct alc_spec *spec = codec->spec;
10405
10406 spec->autocfg.hp_pins[0] = 0x15;
10407 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
10408 spec->ext_mic.pin = 0x18;
10409 spec->ext_mic.mux_idx = 0;
10410 spec->int_mic.pin = 0x12;
10411 spec->int_mic.mux_idx = 9;
10412 spec->auto_mic = 1;
4e555fe5
KY
10413}
10414
e8f9ae2a
PT
10415/*
10416 * nec model
10417 * 0x15 = headphone
10418 * 0x16 = internal speaker
10419 * 0x18 = external mic
10420 */
10421
10422static struct snd_kcontrol_new alc262_nec_mixer[] = {
10423 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10424 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10425
10426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10428 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10429
10430 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10431 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10432 { } /* end */
10433};
10434
10435static struct hda_verb alc262_nec_verbs[] = {
10436 /* Unmute Speaker */
10437 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10438
10439 /* Headphone */
10440 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10441 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10442
10443 /* External mic to headphone */
10444 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10445 /* External mic to speaker */
10446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10447 {}
10448};
10449
834be88d
TI
10450/*
10451 * fujitsu model
5d9fab2d
TV
10452 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10453 * 0x1b = port replicator headphone out
834be88d
TI
10454 */
10455
10456#define ALC_HP_EVENT 0x37
10457
10458static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10459 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
10461 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10462 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
10463 {}
10464};
10465
0e31daf7
J
10466static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10467 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10468 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10469 {}
10470};
10471
834be88d 10472static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 10473 .num_items = 3,
834be88d
TI
10474 .items = {
10475 { "Mic", 0x0 },
39d3ed38 10476 { "Int Mic", 0x1 },
834be88d
TI
10477 { "CD", 0x4 },
10478 },
10479};
10480
9c7f852e
TI
10481static struct hda_input_mux alc262_HP_capture_source = {
10482 .num_items = 5,
10483 .items = {
10484 { "Mic", 0x0 },
accbe498 10485 { "Front Mic", 0x1 },
9c7f852e
TI
10486 { "Line", 0x2 },
10487 { "CD", 0x4 },
10488 { "AUX IN", 0x6 },
10489 },
10490};
10491
accbe498 10492static struct hda_input_mux alc262_HP_D7000_capture_source = {
10493 .num_items = 4,
10494 .items = {
10495 { "Mic", 0x0 },
10496 { "Front Mic", 0x2 },
10497 { "Line", 0x1 },
10498 { "CD", 0x4 },
10499 },
10500};
10501
ebc7a406 10502/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
10503static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10504{
10505 struct alc_spec *spec = codec->spec;
10506 unsigned int mute;
10507
f12ab1e0 10508 if (force || !spec->sense_updated) {
ebc7a406 10509 unsigned int present;
834be88d
TI
10510 /* need to execute and sync at first */
10511 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
10512 /* check laptop HP jack */
10513 present = snd_hda_codec_read(codec, 0x14, 0,
10514 AC_VERB_GET_PIN_SENSE, 0);
10515 /* need to execute and sync at first */
10516 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10517 /* check docking HP jack */
10518 present |= snd_hda_codec_read(codec, 0x1b, 0,
10519 AC_VERB_GET_PIN_SENSE, 0);
10520 if (present & AC_PINSENSE_PRESENCE)
10521 spec->jack_present = 1;
10522 else
10523 spec->jack_present = 0;
834be88d
TI
10524 spec->sense_updated = 1;
10525 }
ebc7a406
TI
10526 /* unmute internal speaker only if both HPs are unplugged and
10527 * master switch is on
10528 */
10529 if (spec->jack_present)
10530 mute = HDA_AMP_MUTE;
10531 else
834be88d 10532 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
10533 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10534 HDA_AMP_MUTE, mute);
834be88d
TI
10535}
10536
10537/* unsolicited event for HP jack sensing */
10538static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10539 unsigned int res)
10540{
10541 if ((res >> 26) != ALC_HP_EVENT)
10542 return;
10543 alc262_fujitsu_automute(codec, 1);
10544}
10545
ebc7a406
TI
10546static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10547{
10548 alc262_fujitsu_automute(codec, 1);
10549}
10550
834be88d 10551/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
10552static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10553 .ops = &snd_hda_bind_vol,
10554 .values = {
10555 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10556 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10557 0
10558 },
10559};
834be88d 10560
0e31daf7
J
10561/* mute/unmute internal speaker according to the hp jack and mute state */
10562static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10563{
10564 struct alc_spec *spec = codec->spec;
10565 unsigned int mute;
10566
10567 if (force || !spec->sense_updated) {
10568 unsigned int present_int_hp;
10569 /* need to execute and sync at first */
10570 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10571 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10572 AC_VERB_GET_PIN_SENSE, 0);
10573 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10574 spec->sense_updated = 1;
10575 }
10576 if (spec->jack_present) {
10577 /* mute internal speaker */
10578 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10579 HDA_AMP_MUTE, HDA_AMP_MUTE);
10580 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10581 HDA_AMP_MUTE, HDA_AMP_MUTE);
10582 } else {
10583 /* unmute internal speaker if necessary */
10584 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10585 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10586 HDA_AMP_MUTE, mute);
10587 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10588 HDA_AMP_MUTE, mute);
10589 }
10590}
10591
10592/* unsolicited event for HP jack sensing */
10593static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10594 unsigned int res)
10595{
10596 if ((res >> 26) != ALC_HP_EVENT)
10597 return;
10598 alc262_lenovo_3000_automute(codec, 1);
10599}
10600
8de56b7d
TI
10601static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
10602 int dir, int idx, long *valp)
10603{
10604 int i, change = 0;
10605
10606 for (i = 0; i < 2; i++, valp++)
10607 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
10608 HDA_AMP_MUTE,
10609 *valp ? 0 : HDA_AMP_MUTE);
10610 return change;
10611}
10612
834be88d
TI
10613/* bind hp and internal speaker mute (with plug check) */
10614static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10615 struct snd_ctl_elem_value *ucontrol)
10616{
10617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10618 long *valp = ucontrol->value.integer.value;
10619 int change;
10620
8de56b7d
TI
10621 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
10622 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
10623 if (change)
10624 alc262_fujitsu_automute(codec, 0);
834be88d
TI
10625 return change;
10626}
10627
10628static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 10629 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
10630 {
10631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10632 .name = "Master Playback Switch",
10633 .info = snd_hda_mixer_amp_switch_info,
10634 .get = snd_hda_mixer_amp_switch_get,
10635 .put = alc262_fujitsu_master_sw_put,
10636 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10637 },
10638 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10639 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10640 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10641 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
10643 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10644 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10645 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
10646 { } /* end */
10647};
10648
0e31daf7
J
10649/* bind hp and internal speaker mute (with plug check) */
10650static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10651 struct snd_ctl_elem_value *ucontrol)
10652{
10653 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10654 long *valp = ucontrol->value.integer.value;
10655 int change;
10656
8de56b7d 10657 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
10658 if (change)
10659 alc262_lenovo_3000_automute(codec, 0);
10660 return change;
10661}
10662
10663static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10664 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10665 {
10666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10667 .name = "Master Playback Switch",
10668 .info = snd_hda_mixer_amp_switch_info,
10669 .get = snd_hda_mixer_amp_switch_get,
10670 .put = alc262_lenovo_3000_master_sw_put,
10671 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10672 },
10673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10675 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10678 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10679 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10680 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10681 { } /* end */
10682};
10683
9f99a638
HM
10684static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10685 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 10686 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
10687 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10688 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10689 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10690 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10691 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10692 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10693 { } /* end */
10694};
10695
304dcaac
TI
10696/* additional init verbs for Benq laptops */
10697static struct hda_verb alc262_EAPD_verbs[] = {
10698 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10699 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10700 {}
10701};
10702
83c34218
KY
10703static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10704 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10705 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10706
10707 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10708 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10709 {}
10710};
10711
f651b50b
TD
10712/* Samsung Q1 Ultra Vista model setup */
10713static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
10714 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10715 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
10716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10718 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 10719 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
10720 { } /* end */
10721};
10722
10723static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
10724 /* output mixer */
10725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10728 /* speaker */
10729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10733 /* HP */
f651b50b 10734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
10735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10737 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10738 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10739 /* internal mic */
10740 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10742 /* ADC, choose mic */
10743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10744 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10747 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10749 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10750 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10751 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
10753 {}
10754};
10755
f651b50b
TD
10756/* mute/unmute internal speaker according to the hp jack and mute state */
10757static void alc262_ultra_automute(struct hda_codec *codec)
10758{
10759 struct alc_spec *spec = codec->spec;
10760 unsigned int mute;
f651b50b 10761
bb9f76cd
TI
10762 mute = 0;
10763 /* auto-mute only when HP is used as HP */
10764 if (!spec->cur_mux[0]) {
10765 unsigned int present;
10766 /* need to execute and sync at first */
10767 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10768 present = snd_hda_codec_read(codec, 0x15, 0,
10769 AC_VERB_GET_PIN_SENSE, 0);
10770 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10771 if (spec->jack_present)
10772 mute = HDA_AMP_MUTE;
f651b50b 10773 }
bb9f76cd
TI
10774 /* mute/unmute internal speaker */
10775 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10776 HDA_AMP_MUTE, mute);
10777 /* mute/unmute HP */
10778 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10779 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
10780}
10781
10782/* unsolicited event for HP jack sensing */
10783static void alc262_ultra_unsol_event(struct hda_codec *codec,
10784 unsigned int res)
10785{
10786 if ((res >> 26) != ALC880_HP_EVENT)
10787 return;
10788 alc262_ultra_automute(codec);
10789}
10790
bb9f76cd
TI
10791static struct hda_input_mux alc262_ultra_capture_source = {
10792 .num_items = 2,
10793 .items = {
10794 { "Mic", 0x1 },
10795 { "Headphone", 0x7 },
10796 },
10797};
10798
10799static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10800 struct snd_ctl_elem_value *ucontrol)
10801{
10802 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10803 struct alc_spec *spec = codec->spec;
10804 int ret;
10805
54cbc9ab 10806 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
10807 if (!ret)
10808 return 0;
10809 /* reprogram the HP pin as mic or HP according to the input source */
10810 snd_hda_codec_write_cache(codec, 0x15, 0,
10811 AC_VERB_SET_PIN_WIDGET_CONTROL,
10812 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10813 alc262_ultra_automute(codec); /* mute/unmute HP */
10814 return ret;
10815}
10816
10817static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10818 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10819 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10820 {
10821 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10822 .name = "Capture Source",
54cbc9ab
TI
10823 .info = alc_mux_enum_info,
10824 .get = alc_mux_enum_get,
bb9f76cd
TI
10825 .put = alc262_ultra_mux_enum_put,
10826 },
10827 { } /* end */
10828};
10829
c3fc1f50
TI
10830/* We use two mixers depending on the output pin; 0x16 is a mono output
10831 * and thus it's bound with a different mixer.
10832 * This function returns which mixer amp should be used.
10833 */
10834static int alc262_check_volbit(hda_nid_t nid)
10835{
10836 if (!nid)
10837 return 0;
10838 else if (nid == 0x16)
10839 return 2;
10840 else
10841 return 1;
10842}
10843
10844static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10845 const char *pfx, int *vbits)
10846{
10847 char name[32];
10848 unsigned long val;
10849 int vbit;
10850
10851 vbit = alc262_check_volbit(nid);
10852 if (!vbit)
10853 return 0;
10854 if (*vbits & vbit) /* a volume control for this mixer already there */
10855 return 0;
10856 *vbits |= vbit;
10857 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
10858 if (vbit == 2)
10859 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
10860 else
10861 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
10862 return add_control(spec, ALC_CTL_WIDGET_VOL, name, val);
10863}
10864
10865static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
10866 const char *pfx)
10867{
10868 char name[32];
10869 unsigned long val;
10870
10871 if (!nid)
10872 return 0;
10873 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
10874 if (nid == 0x16)
10875 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
10876 else
10877 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
10878 return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val);
10879}
10880
df694daa 10881/* add playback controls from the parsed DAC table */
f12ab1e0
TI
10882static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10883 const struct auto_pin_cfg *cfg)
df694daa 10884{
c3fc1f50
TI
10885 const char *pfx;
10886 int vbits;
df694daa
KY
10887 int err;
10888
10889 spec->multiout.num_dacs = 1; /* only use one dac */
10890 spec->multiout.dac_nids = spec->private_dac_nids;
10891 spec->multiout.dac_nids[0] = 2;
10892
c3fc1f50
TI
10893 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
10894 pfx = "Master";
10895 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10896 pfx = "Speaker";
10897 else
10898 pfx = "Front";
10899 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
10900 if (err < 0)
10901 return err;
10902 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
10903 if (err < 0)
10904 return err;
10905 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
10906 if (err < 0)
10907 return err;
df694daa 10908
c3fc1f50
TI
10909 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
10910 alc262_check_volbit(cfg->speaker_pins[0]) |
10911 alc262_check_volbit(cfg->hp_pins[0]);
10912 if (vbits == 1 || vbits == 2)
10913 pfx = "Master"; /* only one mixer is used */
10914 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10915 pfx = "Speaker";
10916 else
10917 pfx = "Front";
10918 vbits = 0;
10919 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
10920 if (err < 0)
10921 return err;
10922 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
10923 &vbits);
10924 if (err < 0)
10925 return err;
10926 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
10927 &vbits);
10928 if (err < 0)
10929 return err;
f12ab1e0 10930 return 0;
df694daa
KY
10931}
10932
05f5f477
TI
10933#define alc262_auto_create_input_ctls \
10934 alc880_auto_create_input_ctls
df694daa
KY
10935
10936/*
10937 * generic initialization of ADC, input mixers and output mixers
10938 */
10939static struct hda_verb alc262_volume_init_verbs[] = {
10940 /*
10941 * Unmute ADC0-2 and set the default input to mic-in
10942 */
10943 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10945 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10946 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10947 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10948 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10949
cb53c626 10950 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10951 * mixer widget
f12ab1e0
TI
10952 * Note: PASD motherboards uses the Line In 2 as the input for
10953 * front panel mic (mic 2)
df694daa
KY
10954 */
10955 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10961
10962 /*
10963 * Set up output mixers (0x0c - 0x0f)
10964 */
10965 /* set vol=0 to output mixers */
10966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10969
df694daa
KY
10970 /* set up input amps for analog loopback */
10971 /* Amp Indices: DAC = 0, mixer = 1 */
10972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10975 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10977 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10978
10979 /* FIXME: use matrix-type input source selection */
10980 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10981 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10982 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10983 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10986 /* Input mixer2 */
10987 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10988 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10989 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10990 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10991 /* Input mixer3 */
10992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10996
10997 { }
10998};
10999
9c7f852e
TI
11000static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11001 /*
11002 * Unmute ADC0-2 and set the default input to mic-in
11003 */
11004 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11006 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11008 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11010
cb53c626 11011 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11012 * mixer widget
f12ab1e0
TI
11013 * Note: PASD motherboards uses the Line In 2 as the input for
11014 * front panel mic (mic 2)
9c7f852e
TI
11015 */
11016 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11017 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11018 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11024
9c7f852e
TI
11025 /*
11026 * Set up output mixers (0x0c - 0x0e)
11027 */
11028 /* set vol=0 to output mixers */
11029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11032
11033 /* set up input amps for analog loopback */
11034 /* Amp Indices: DAC = 0, mixer = 1 */
11035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11037 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11038 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11039 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11040 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11041
ce875f07 11042 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11043 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11044 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11045
11046 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11047 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11048
11049 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11050 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11051
11052 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11053 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11054 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11055 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11056 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11057
0e4835c1 11058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11059 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11060 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11061 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11062 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11063 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11064
11065
11066 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
11067 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11068 /* Input mixer1: only unmute Mic */
9c7f852e 11069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11071 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11078 /* Input mixer2 */
11079 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11085 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11086 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11087 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11088 /* Input mixer3 */
11089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11092 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11093 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11094 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11095 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11096 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 11098
ce875f07
TI
11099 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11100
9c7f852e
TI
11101 { }
11102};
11103
cd7509a4
KY
11104static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11105 /*
11106 * Unmute ADC0-2 and set the default input to mic-in
11107 */
11108 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11110 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11111 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11112 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11114
cb53c626 11115 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
11116 * mixer widget
11117 * Note: PASD motherboards uses the Line In 2 as the input for front
11118 * panel mic (mic 2)
11119 */
11120 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11124 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11125 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11126 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11127 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11128 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
11129 /*
11130 * Set up output mixers (0x0c - 0x0e)
11131 */
11132 /* set vol=0 to output mixers */
11133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11134 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11135 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11136
11137 /* set up input amps for analog loopback */
11138 /* Amp Indices: DAC = 0, mixer = 1 */
11139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11140 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11141 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11142 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11144 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11145
11146
11147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11152 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11153 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11154
11155 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11157
11158 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11159 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11160
11161 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11162 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11163 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11164 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11165 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11166 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11167
11168 /* FIXME: use matrix-type input source selection */
11169 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11170 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11171 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11172 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11173 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11174 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11175 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11176 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11177 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11178 /* Input mixer2 */
11179 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11180 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11183 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11184 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11185 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11186 /* Input mixer3 */
11187 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11188 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11189 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11190 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11191 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11192 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11193 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11194
ce875f07
TI
11195 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11196
cd7509a4
KY
11197 { }
11198};
11199
9f99a638
HM
11200static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11201
11202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11204 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11205
11206 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11208 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11209 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11210
11211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11212 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11213 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11214 {}
11215};
11216
11217
cb53c626
TI
11218#ifdef CONFIG_SND_HDA_POWER_SAVE
11219#define alc262_loopbacks alc880_loopbacks
11220#endif
11221
def319f9 11222/* pcm configuration: identical with ALC880 */
df694daa
KY
11223#define alc262_pcm_analog_playback alc880_pcm_analog_playback
11224#define alc262_pcm_analog_capture alc880_pcm_analog_capture
11225#define alc262_pcm_digital_playback alc880_pcm_digital_playback
11226#define alc262_pcm_digital_capture alc880_pcm_digital_capture
11227
11228/*
11229 * BIOS auto configuration
11230 */
11231static int alc262_parse_auto_config(struct hda_codec *codec)
11232{
11233 struct alc_spec *spec = codec->spec;
11234 int err;
11235 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11236
f12ab1e0
TI
11237 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11238 alc262_ignore);
11239 if (err < 0)
df694daa 11240 return err;
e64f14f4 11241 if (!spec->autocfg.line_outs) {
0852d7a6 11242 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
11243 spec->multiout.max_channels = 2;
11244 spec->no_analog = 1;
11245 goto dig_only;
11246 }
df694daa 11247 return 0; /* can't find valid BIOS pin config */
e64f14f4 11248 }
f12ab1e0
TI
11249 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11250 if (err < 0)
11251 return err;
05f5f477 11252 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 11253 if (err < 0)
df694daa
KY
11254 return err;
11255
11256 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11257
e64f14f4 11258 dig_only:
0852d7a6 11259 if (spec->autocfg.dig_outs) {
df694daa 11260 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 11261 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 11262 }
df694daa
KY
11263 if (spec->autocfg.dig_in_pin)
11264 spec->dig_in_nid = ALC262_DIGIN_NID;
11265
603c4019 11266 if (spec->kctls.list)
d88897ea 11267 add_mixer(spec, spec->kctls.list);
df694daa 11268
d88897ea 11269 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 11270 spec->num_mux_defs = 1;
61b9b9b1 11271 spec->input_mux = &spec->private_imux[0];
df694daa 11272
776e184e
TI
11273 err = alc_auto_add_mic_boost(codec);
11274 if (err < 0)
11275 return err;
11276
4a79ba34
TI
11277 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11278
df694daa
KY
11279 return 1;
11280}
11281
11282#define alc262_auto_init_multi_out alc882_auto_init_multi_out
11283#define alc262_auto_init_hp_out alc882_auto_init_hp_out
11284#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 11285#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
11286
11287
11288/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 11289static void alc262_auto_init(struct hda_codec *codec)
df694daa 11290{
f6c7e546 11291 struct alc_spec *spec = codec->spec;
df694daa
KY
11292 alc262_auto_init_multi_out(codec);
11293 alc262_auto_init_hp_out(codec);
11294 alc262_auto_init_analog_input(codec);
f511b01c 11295 alc262_auto_init_input_src(codec);
f6c7e546 11296 if (spec->unsol_event)
7fb0d78f 11297 alc_inithook(codec);
df694daa
KY
11298}
11299
11300/*
11301 * configuration and preset
11302 */
f5fcc13c
TI
11303static const char *alc262_models[ALC262_MODEL_LAST] = {
11304 [ALC262_BASIC] = "basic",
11305 [ALC262_HIPPO] = "hippo",
11306 [ALC262_HIPPO_1] = "hippo_1",
11307 [ALC262_FUJITSU] = "fujitsu",
11308 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 11309 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 11310 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 11311 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 11312 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
11313 [ALC262_BENQ_T31] = "benq-t31",
11314 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 11315 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 11316 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 11317 [ALC262_ULTRA] = "ultra",
0e31daf7 11318 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 11319 [ALC262_NEC] = "nec",
ba340e82 11320 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
11321 [ALC262_AUTO] = "auto",
11322};
11323
11324static struct snd_pci_quirk alc262_cfg_tbl[] = {
11325 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 11326 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
11327 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11328 ALC262_HP_BPC),
11329 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11330 ALC262_HP_BPC),
53eff7e1
TI
11331 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11332 ALC262_HP_BPC),
cd7509a4 11333 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11334 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11335 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11336 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11337 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11338 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11339 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11340 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
11341 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11342 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11343 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
11344 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11345 ALC262_HP_TC_T5735),
8c427226 11346 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 11347 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 11348 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 11349 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 11350 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 11351 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
f872a919
TI
11352 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11353 ALC262_SONY_ASSAMD),
36ca6e13 11354 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 11355 ALC262_TOSHIBA_RX1),
80ffe869 11356 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 11357 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 11358 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 11359 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
11360 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11361 ALC262_ULTRA),
3e420e78 11362 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 11363 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
11364 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11365 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11366 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
11367 {}
11368};
11369
11370static struct alc_config_preset alc262_presets[] = {
11371 [ALC262_BASIC] = {
11372 .mixers = { alc262_base_mixer },
11373 .init_verbs = { alc262_init_verbs },
11374 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11375 .dac_nids = alc262_dac_nids,
11376 .hp_nid = 0x03,
11377 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11378 .channel_mode = alc262_modes,
a3bcba38 11379 .input_mux = &alc262_capture_source,
df694daa 11380 },
ccc656ce 11381 [ALC262_HIPPO] = {
42171c17 11382 .mixers = { alc262_hippo_mixer },
6732bd0d 11383 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
11384 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11385 .dac_nids = alc262_dac_nids,
11386 .hp_nid = 0x03,
11387 .dig_out_nid = ALC262_DIGOUT_NID,
11388 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11389 .channel_mode = alc262_modes,
11390 .input_mux = &alc262_capture_source,
11391 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11392 .setup = alc262_hippo_setup,
11393 .init_hook = alc262_hippo_automute,
ccc656ce
KY
11394 },
11395 [ALC262_HIPPO_1] = {
11396 .mixers = { alc262_hippo1_mixer },
11397 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11398 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11399 .dac_nids = alc262_dac_nids,
11400 .hp_nid = 0x02,
11401 .dig_out_nid = ALC262_DIGOUT_NID,
11402 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11403 .channel_mode = alc262_modes,
11404 .input_mux = &alc262_capture_source,
42171c17 11405 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11406 .setup = alc262_hippo1_setup,
11407 .init_hook = alc262_hippo_automute,
ccc656ce 11408 },
834be88d
TI
11409 [ALC262_FUJITSU] = {
11410 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
11411 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11412 alc262_fujitsu_unsol_verbs },
834be88d
TI
11413 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11414 .dac_nids = alc262_dac_nids,
11415 .hp_nid = 0x03,
11416 .dig_out_nid = ALC262_DIGOUT_NID,
11417 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11418 .channel_mode = alc262_modes,
11419 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 11420 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 11421 .init_hook = alc262_fujitsu_init_hook,
834be88d 11422 },
9c7f852e
TI
11423 [ALC262_HP_BPC] = {
11424 .mixers = { alc262_HP_BPC_mixer },
11425 .init_verbs = { alc262_HP_BPC_init_verbs },
11426 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11427 .dac_nids = alc262_dac_nids,
11428 .hp_nid = 0x03,
11429 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11430 .channel_mode = alc262_modes,
11431 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
11432 .unsol_event = alc262_hp_bpc_unsol_event,
11433 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 11434 },
cd7509a4
KY
11435 [ALC262_HP_BPC_D7000_WF] = {
11436 .mixers = { alc262_HP_BPC_WildWest_mixer },
11437 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11438 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11439 .dac_nids = alc262_dac_nids,
11440 .hp_nid = 0x03,
11441 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11442 .channel_mode = alc262_modes,
accbe498 11443 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11444 .unsol_event = alc262_hp_wildwest_unsol_event,
11445 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11446 },
cd7509a4
KY
11447 [ALC262_HP_BPC_D7000_WL] = {
11448 .mixers = { alc262_HP_BPC_WildWest_mixer,
11449 alc262_HP_BPC_WildWest_option_mixer },
11450 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11451 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11452 .dac_nids = alc262_dac_nids,
11453 .hp_nid = 0x03,
11454 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11455 .channel_mode = alc262_modes,
accbe498 11456 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11457 .unsol_event = alc262_hp_wildwest_unsol_event,
11458 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11459 },
66d2a9d6
KY
11460 [ALC262_HP_TC_T5735] = {
11461 .mixers = { alc262_hp_t5735_mixer },
11462 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11463 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11464 .dac_nids = alc262_dac_nids,
11465 .hp_nid = 0x03,
11466 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11467 .channel_mode = alc262_modes,
11468 .input_mux = &alc262_capture_source,
a9fd4f3f 11469 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
11470 .setup = alc262_hp_t5735_setup,
11471 .init_hook = alc_automute_amp,
8c427226
KY
11472 },
11473 [ALC262_HP_RP5700] = {
11474 .mixers = { alc262_hp_rp5700_mixer },
11475 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11476 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11477 .dac_nids = alc262_dac_nids,
11478 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11479 .channel_mode = alc262_modes,
11480 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 11481 },
304dcaac
TI
11482 [ALC262_BENQ_ED8] = {
11483 .mixers = { alc262_base_mixer },
11484 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11485 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11486 .dac_nids = alc262_dac_nids,
11487 .hp_nid = 0x03,
11488 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11489 .channel_mode = alc262_modes,
11490 .input_mux = &alc262_capture_source,
f12ab1e0 11491 },
272a527c
KY
11492 [ALC262_SONY_ASSAMD] = {
11493 .mixers = { alc262_sony_mixer },
11494 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11495 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11496 .dac_nids = alc262_dac_nids,
11497 .hp_nid = 0x02,
11498 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11499 .channel_mode = alc262_modes,
11500 .input_mux = &alc262_capture_source,
11501 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11502 .setup = alc262_hippo_setup,
11503 .init_hook = alc262_hippo_automute,
83c34218
KY
11504 },
11505 [ALC262_BENQ_T31] = {
11506 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
11507 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11508 alc_hp15_unsol_verbs },
83c34218
KY
11509 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11510 .dac_nids = alc262_dac_nids,
11511 .hp_nid = 0x03,
11512 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11513 .channel_mode = alc262_modes,
11514 .input_mux = &alc262_capture_source,
11515 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11516 .setup = alc262_hippo_setup,
11517 .init_hook = alc262_hippo_automute,
ea1fb29a 11518 },
f651b50b 11519 [ALC262_ULTRA] = {
f9e336f6
TI
11520 .mixers = { alc262_ultra_mixer },
11521 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 11522 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
11523 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11524 .dac_nids = alc262_dac_nids,
f651b50b
TD
11525 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11526 .channel_mode = alc262_modes,
11527 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
11528 .adc_nids = alc262_adc_nids, /* ADC0 */
11529 .capsrc_nids = alc262_capsrc_nids,
11530 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
11531 .unsol_event = alc262_ultra_unsol_event,
11532 .init_hook = alc262_ultra_automute,
11533 },
0e31daf7
J
11534 [ALC262_LENOVO_3000] = {
11535 .mixers = { alc262_lenovo_3000_mixer },
11536 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11537 alc262_lenovo_3000_unsol_verbs },
11538 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11539 .dac_nids = alc262_dac_nids,
11540 .hp_nid = 0x03,
11541 .dig_out_nid = ALC262_DIGOUT_NID,
11542 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11543 .channel_mode = alc262_modes,
11544 .input_mux = &alc262_fujitsu_capture_source,
11545 .unsol_event = alc262_lenovo_3000_unsol_event,
11546 },
e8f9ae2a
PT
11547 [ALC262_NEC] = {
11548 .mixers = { alc262_nec_mixer },
11549 .init_verbs = { alc262_nec_verbs },
11550 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11551 .dac_nids = alc262_dac_nids,
11552 .hp_nid = 0x03,
11553 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11554 .channel_mode = alc262_modes,
11555 .input_mux = &alc262_capture_source,
11556 },
4e555fe5
KY
11557 [ALC262_TOSHIBA_S06] = {
11558 .mixers = { alc262_toshiba_s06_mixer },
11559 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11560 alc262_eapd_verbs },
11561 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11562 .capsrc_nids = alc262_dmic_capsrc_nids,
11563 .dac_nids = alc262_dac_nids,
11564 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 11565 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
11566 .dig_out_nid = ALC262_DIGOUT_NID,
11567 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11568 .channel_mode = alc262_modes,
4f5d1706
TI
11569 .unsol_event = alc_sku_unsol_event,
11570 .setup = alc262_toshiba_s06_setup,
11571 .init_hook = alc_inithook,
4e555fe5 11572 },
9f99a638
HM
11573 [ALC262_TOSHIBA_RX1] = {
11574 .mixers = { alc262_toshiba_rx1_mixer },
11575 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11576 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11577 .dac_nids = alc262_dac_nids,
11578 .hp_nid = 0x03,
11579 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11580 .channel_mode = alc262_modes,
11581 .input_mux = &alc262_capture_source,
11582 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11583 .setup = alc262_hippo_setup,
11584 .init_hook = alc262_hippo_automute,
9f99a638 11585 },
ba340e82
TV
11586 [ALC262_TYAN] = {
11587 .mixers = { alc262_tyan_mixer },
11588 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11589 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11590 .dac_nids = alc262_dac_nids,
11591 .hp_nid = 0x02,
11592 .dig_out_nid = ALC262_DIGOUT_NID,
11593 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11594 .channel_mode = alc262_modes,
11595 .input_mux = &alc262_capture_source,
a9fd4f3f 11596 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
11597 .setup = alc262_tyan_setup,
11598 .init_hook = alc_automute_amp,
ba340e82 11599 },
df694daa
KY
11600};
11601
11602static int patch_alc262(struct hda_codec *codec)
11603{
11604 struct alc_spec *spec;
11605 int board_config;
11606 int err;
11607
dc041e0b 11608 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11609 if (spec == NULL)
11610 return -ENOMEM;
11611
11612 codec->spec = spec;
11613#if 0
f12ab1e0
TI
11614 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11615 * under-run
11616 */
df694daa
KY
11617 {
11618 int tmp;
11619 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11620 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11621 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11622 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11623 }
11624#endif
11625
2c3bf9ab
TI
11626 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11627
f5fcc13c
TI
11628 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11629 alc262_models,
11630 alc262_cfg_tbl);
cd7509a4 11631
f5fcc13c 11632 if (board_config < 0) {
9a11f1aa
TI
11633 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11634 codec->chip_name);
df694daa
KY
11635 board_config = ALC262_AUTO;
11636 }
11637
11638 if (board_config == ALC262_AUTO) {
11639 /* automatic parse from the BIOS config */
11640 err = alc262_parse_auto_config(codec);
11641 if (err < 0) {
11642 alc_free(codec);
11643 return err;
f12ab1e0 11644 } else if (!err) {
9c7f852e
TI
11645 printk(KERN_INFO
11646 "hda_codec: Cannot set up configuration "
11647 "from BIOS. Using base mode...\n");
df694daa
KY
11648 board_config = ALC262_BASIC;
11649 }
11650 }
11651
07eba61d
TI
11652 if (!spec->no_analog) {
11653 err = snd_hda_attach_beep_device(codec, 0x1);
11654 if (err < 0) {
11655 alc_free(codec);
11656 return err;
11657 }
680cd536
KK
11658 }
11659
df694daa 11660 if (board_config != ALC262_AUTO)
e9c364c0 11661 setup_preset(codec, &alc262_presets[board_config]);
df694daa 11662
df694daa
KY
11663 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11664 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 11665
df694daa
KY
11666 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11667 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11668
f12ab1e0 11669 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
11670 int i;
11671 /* check whether the digital-mic has to be supported */
11672 for (i = 0; i < spec->input_mux->num_items; i++) {
11673 if (spec->input_mux->items[i].index >= 9)
11674 break;
11675 }
11676 if (i < spec->input_mux->num_items) {
11677 /* use only ADC0 */
11678 spec->adc_nids = alc262_dmic_adc_nids;
11679 spec->num_adc_nids = 1;
11680 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 11681 } else {
8c927b4a
TI
11682 /* all analog inputs */
11683 /* check whether NID 0x07 is valid */
11684 unsigned int wcap = get_wcaps(codec, 0x07);
11685
11686 /* get type */
a22d543a 11687 wcap = get_wcaps_type(wcap);
8c927b4a
TI
11688 if (wcap != AC_WID_AUD_IN) {
11689 spec->adc_nids = alc262_adc_nids_alt;
11690 spec->num_adc_nids =
11691 ARRAY_SIZE(alc262_adc_nids_alt);
11692 spec->capsrc_nids = alc262_capsrc_nids_alt;
11693 } else {
11694 spec->adc_nids = alc262_adc_nids;
11695 spec->num_adc_nids =
11696 ARRAY_SIZE(alc262_adc_nids);
11697 spec->capsrc_nids = alc262_capsrc_nids;
11698 }
df694daa
KY
11699 }
11700 }
e64f14f4 11701 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 11702 set_capture_mixer(codec);
07eba61d
TI
11703 if (!spec->no_analog)
11704 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 11705
2134ea4f
TI
11706 spec->vmaster_nid = 0x0c;
11707
df694daa
KY
11708 codec->patch_ops = alc_patch_ops;
11709 if (board_config == ALC262_AUTO)
ae6b813a 11710 spec->init_hook = alc262_auto_init;
cb53c626
TI
11711#ifdef CONFIG_SND_HDA_POWER_SAVE
11712 if (!spec->loopback.amplist)
11713 spec->loopback.amplist = alc262_loopbacks;
11714#endif
daead538 11715 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 11716
df694daa
KY
11717 return 0;
11718}
11719
a361d84b
KY
11720/*
11721 * ALC268 channel source setting (2 channel)
11722 */
11723#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11724#define alc268_modes alc260_modes
ea1fb29a 11725
a361d84b
KY
11726static hda_nid_t alc268_dac_nids[2] = {
11727 /* front, hp */
11728 0x02, 0x03
11729};
11730
11731static hda_nid_t alc268_adc_nids[2] = {
11732 /* ADC0-1 */
11733 0x08, 0x07
11734};
11735
11736static hda_nid_t alc268_adc_nids_alt[1] = {
11737 /* ADC0 */
11738 0x08
11739};
11740
e1406348
TI
11741static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11742
a361d84b
KY
11743static struct snd_kcontrol_new alc268_base_mixer[] = {
11744 /* output mixer control */
11745 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11746 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11747 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11748 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
11749 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11750 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11751 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
11752 { }
11753};
11754
42171c17
TI
11755static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11756 /* output mixer control */
11757 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11758 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11759 ALC262_HIPPO_MASTER_SWITCH,
11760 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11761 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11762 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11763 { }
11764};
11765
aef9d318
TI
11766/* bind Beep switches of both NID 0x0f and 0x10 */
11767static struct hda_bind_ctls alc268_bind_beep_sw = {
11768 .ops = &snd_hda_bind_sw,
11769 .values = {
11770 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11771 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11772 0
11773 },
11774};
11775
11776static struct snd_kcontrol_new alc268_beep_mixer[] = {
11777 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11778 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11779 { }
11780};
11781
d1a991a6
KY
11782static struct hda_verb alc268_eapd_verbs[] = {
11783 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11784 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11785 { }
11786};
11787
d273809e 11788/* Toshiba specific */
d273809e
TI
11789static struct hda_verb alc268_toshiba_verbs[] = {
11790 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11791 { } /* end */
11792};
11793
11794/* Acer specific */
889c4395 11795/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
11796static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11797 .ops = &snd_hda_bind_vol,
11798 .values = {
11799 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11800 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11801 0
11802 },
11803};
11804
889c4395
TI
11805/* mute/unmute internal speaker according to the hp jack and mute state */
11806static void alc268_acer_automute(struct hda_codec *codec, int force)
11807{
11808 struct alc_spec *spec = codec->spec;
11809 unsigned int mute;
11810
11811 if (force || !spec->sense_updated) {
11812 unsigned int present;
11813 present = snd_hda_codec_read(codec, 0x14, 0,
11814 AC_VERB_GET_PIN_SENSE, 0);
11815 spec->jack_present = (present & 0x80000000) != 0;
11816 spec->sense_updated = 1;
11817 }
11818 if (spec->jack_present)
11819 mute = HDA_AMP_MUTE; /* mute internal speaker */
11820 else /* unmute internal speaker if necessary */
11821 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11822 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11823 HDA_AMP_MUTE, mute);
11824}
11825
11826
11827/* bind hp and internal speaker mute (with plug check) */
11828static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11829 struct snd_ctl_elem_value *ucontrol)
11830{
11831 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11832 long *valp = ucontrol->value.integer.value;
11833 int change;
11834
8de56b7d 11835 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
11836 if (change)
11837 alc268_acer_automute(codec, 0);
11838 return change;
11839}
d273809e 11840
8ef355da
KY
11841static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11842 /* output mixer control */
11843 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11844 {
11845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11846 .name = "Master Playback Switch",
11847 .info = snd_hda_mixer_amp_switch_info,
11848 .get = snd_hda_mixer_amp_switch_get,
11849 .put = alc268_acer_master_sw_put,
11850 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11851 },
11852 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11853 { }
11854};
11855
d273809e
TI
11856static struct snd_kcontrol_new alc268_acer_mixer[] = {
11857 /* output mixer control */
11858 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11859 {
11860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11861 .name = "Master Playback Switch",
11862 .info = snd_hda_mixer_amp_switch_info,
11863 .get = snd_hda_mixer_amp_switch_get,
11864 .put = alc268_acer_master_sw_put,
11865 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11866 },
33bf17ab
TI
11867 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11868 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11869 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
11870 { }
11871};
11872
c238b4f4
TI
11873static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11874 /* output mixer control */
11875 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11876 {
11877 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11878 .name = "Master Playback Switch",
11879 .info = snd_hda_mixer_amp_switch_info,
11880 .get = snd_hda_mixer_amp_switch_get,
11881 .put = alc268_acer_master_sw_put,
11882 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11883 },
11884 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11885 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11886 { }
11887};
11888
8ef355da
KY
11889static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11890 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11891 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11892 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11893 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11894 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11895 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11896 { }
11897};
11898
d273809e 11899static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
11900 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11901 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
11902 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11903 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
11904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11905 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
11906 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11907 { }
11908};
11909
11910/* unsolicited event for HP jack sensing */
42171c17 11911#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
11912#define alc268_toshiba_setup alc262_hippo_setup
11913#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
11914
11915static void alc268_acer_unsol_event(struct hda_codec *codec,
11916 unsigned int res)
11917{
889c4395 11918 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11919 return;
11920 alc268_acer_automute(codec, 1);
11921}
11922
889c4395
TI
11923static void alc268_acer_init_hook(struct hda_codec *codec)
11924{
11925 alc268_acer_automute(codec, 1);
11926}
11927
8ef355da
KY
11928/* toggle speaker-output according to the hp-jack state */
11929static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11930{
11931 unsigned int present;
11932 unsigned char bits;
11933
11934 present = snd_hda_codec_read(codec, 0x15, 0,
11935 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11936 bits = present ? AMP_IN_MUTE(0) : 0;
11937 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11938 AMP_IN_MUTE(0), bits);
11939 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11940 AMP_IN_MUTE(0), bits);
11941}
11942
8ef355da
KY
11943static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11944 unsigned int res)
11945{
4f5d1706
TI
11946 switch (res >> 26) {
11947 case ALC880_HP_EVENT:
8ef355da 11948 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
11949 break;
11950 case ALC880_MIC_EVENT:
11951 alc_mic_automute(codec);
11952 break;
11953 }
11954}
11955
11956static void alc268_acer_lc_setup(struct hda_codec *codec)
11957{
11958 struct alc_spec *spec = codec->spec;
11959 spec->ext_mic.pin = 0x18;
11960 spec->ext_mic.mux_idx = 0;
11961 spec->int_mic.pin = 0x12;
11962 spec->int_mic.mux_idx = 6;
11963 spec->auto_mic = 1;
8ef355da
KY
11964}
11965
11966static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11967{
11968 alc268_aspire_one_speaker_automute(codec);
4f5d1706 11969 alc_mic_automute(codec);
8ef355da
KY
11970}
11971
3866f0b0
TI
11972static struct snd_kcontrol_new alc268_dell_mixer[] = {
11973 /* output mixer control */
11974 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11975 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11976 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11978 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11979 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11980 { }
11981};
11982
11983static struct hda_verb alc268_dell_verbs[] = {
11984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11986 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 11987 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
11988 { }
11989};
11990
11991/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11992static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 11993{
a9fd4f3f 11994 struct alc_spec *spec = codec->spec;
3866f0b0 11995
a9fd4f3f
TI
11996 spec->autocfg.hp_pins[0] = 0x15;
11997 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11998 spec->ext_mic.pin = 0x18;
11999 spec->ext_mic.mux_idx = 0;
12000 spec->int_mic.pin = 0x19;
12001 spec->int_mic.mux_idx = 1;
12002 spec->auto_mic = 1;
3866f0b0
TI
12003}
12004
eb5a6621
HRK
12005static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12007 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12008 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12010 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12011 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12012 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12013 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12014 { }
12015};
12016
12017static struct hda_verb alc267_quanta_il1_verbs[] = {
12018 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12019 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12020 { }
12021};
12022
4f5d1706 12023static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12024{
a9fd4f3f 12025 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12026 spec->autocfg.hp_pins[0] = 0x15;
12027 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12028 spec->ext_mic.pin = 0x18;
12029 spec->ext_mic.mux_idx = 0;
12030 spec->int_mic.pin = 0x19;
12031 spec->int_mic.mux_idx = 1;
12032 spec->auto_mic = 1;
eb5a6621
HRK
12033}
12034
a361d84b
KY
12035/*
12036 * generic initialization of ADC, input mixers and output mixers
12037 */
12038static struct hda_verb alc268_base_init_verbs[] = {
12039 /* Unmute DAC0-1 and set vol = 0 */
12040 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12041 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12042
12043 /*
12044 * Set up output mixers (0x0c - 0x0e)
12045 */
12046 /* set vol=0 to output mixers */
12047 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12048 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12049
12050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12051 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12052
12053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12055 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12056 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12057 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12058 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12059 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12060 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12061
12062 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12064 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12065 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12066 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12067
12068 /* set PCBEEP vol = 0, mute connections */
12069 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12070 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12071 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12072
a9b3aa8a 12073 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12074
a9b3aa8a
JZ
12075 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12077 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 12079
a361d84b
KY
12080 { }
12081};
12082
12083/*
12084 * generic initialization of ADC, input mixers and output mixers
12085 */
12086static struct hda_verb alc268_volume_init_verbs[] = {
12087 /* set output DAC */
4cfb91c6
TI
12088 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12089 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12090
12091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12092 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12093 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12094 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12095 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12096
a361d84b 12097 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12098 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12099 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12100
12101 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12102 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12103
aef9d318
TI
12104 /* set PCBEEP vol = 0, mute connections */
12105 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12107 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
12108
12109 { }
12110};
12111
fdbc6626
TI
12112static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12113 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12114 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12115 { } /* end */
12116};
12117
a361d84b
KY
12118static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12119 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12120 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 12121 _DEFINE_CAPSRC(1),
a361d84b
KY
12122 { } /* end */
12123};
12124
12125static struct snd_kcontrol_new alc268_capture_mixer[] = {
12126 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12127 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12128 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12129 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 12130 _DEFINE_CAPSRC(2),
a361d84b
KY
12131 { } /* end */
12132};
12133
12134static struct hda_input_mux alc268_capture_source = {
12135 .num_items = 4,
12136 .items = {
12137 { "Mic", 0x0 },
12138 { "Front Mic", 0x1 },
12139 { "Line", 0x2 },
12140 { "CD", 0x3 },
12141 },
12142};
12143
0ccb541c 12144static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
12145 .num_items = 3,
12146 .items = {
12147 { "Mic", 0x0 },
12148 { "Internal Mic", 0x1 },
12149 { "Line", 0x2 },
12150 },
12151};
12152
12153static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
12154 .num_items = 3,
12155 .items = {
12156 { "Mic", 0x0 },
12157 { "Internal Mic", 0x6 },
12158 { "Line", 0x2 },
12159 },
12160};
12161
86c53bd2
JW
12162#ifdef CONFIG_SND_DEBUG
12163static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
12164 /* Volume widgets */
12165 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12166 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12167 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12168 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12169 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12170 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12171 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12172 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12173 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12174 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12175 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12176 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12177 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
12178 /* The below appears problematic on some hardwares */
12179 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
12180 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12181 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12182 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12183 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12184
12185 /* Modes for retasking pin widgets */
12186 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12187 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12188 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12189 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12190
12191 /* Controls for GPIO pins, assuming they are configured as outputs */
12192 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12193 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12194 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12195 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12196
12197 /* Switches to allow the digital SPDIF output pin to be enabled.
12198 * The ALC268 does not have an SPDIF input.
12199 */
12200 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12201
12202 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12203 * this output to turn on an external amplifier.
12204 */
12205 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12206 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12207
12208 { } /* end */
12209};
12210#endif
12211
a361d84b
KY
12212/* create input playback/capture controls for the given pin */
12213static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12214 const char *ctlname, int idx)
12215{
12216 char name[32];
3f3b7c1a 12217 hda_nid_t dac;
a361d84b
KY
12218 int err;
12219
12220 sprintf(name, "%s Playback Volume", ctlname);
3f3b7c1a
TI
12221 switch (nid) {
12222 case 0x14:
12223 case 0x16:
12224 dac = 0x02;
12225 break;
12226 case 0x15:
12227 dac = 0x03;
12228 break;
12229 default:
12230 return 0;
12231 }
12232 if (spec->multiout.dac_nids[0] != dac &&
12233 spec->multiout.dac_nids[1] != dac) {
a361d84b 12234 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3f3b7c1a 12235 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
12236 HDA_OUTPUT));
12237 if (err < 0)
12238 return err;
3f3b7c1a
TI
12239 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12240 }
12241
a361d84b 12242 sprintf(name, "%s Playback Switch", ctlname);
3f3b7c1a
TI
12243 if (nid != 0x16)
12244 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
a361d84b 12245 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a
TI
12246 else /* mono */
12247 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12248 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
12249 if (err < 0)
12250 return err;
12251 return 0;
12252}
12253
12254/* add playback controls from the parsed DAC table */
12255static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12256 const struct auto_pin_cfg *cfg)
12257{
12258 hda_nid_t nid;
12259 int err;
12260
a361d84b 12261 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
12262
12263 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
12264 if (nid) {
12265 const char *name;
12266 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12267 name = "Speaker";
12268 else
12269 name = "Front";
12270 err = alc268_new_analog_output(spec, nid, name, 0);
12271 if (err < 0)
12272 return err;
12273 }
a361d84b
KY
12274
12275 nid = cfg->speaker_pins[0];
12276 if (nid == 0x1d) {
12277 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12278 "Speaker Playback Volume",
12279 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12280 if (err < 0)
12281 return err;
3f3b7c1a
TI
12282 } else {
12283 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12284 if (err < 0)
12285 return err;
a361d84b
KY
12286 }
12287 nid = cfg->hp_pins[0];
3f3b7c1a
TI
12288 if (nid) {
12289 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12290 if (err < 0)
12291 return err;
12292 }
a361d84b
KY
12293
12294 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12295 if (nid == 0x16) {
12296 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12297 "Mono Playback Switch",
3f3b7c1a 12298 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
12299 if (err < 0)
12300 return err;
12301 }
ea1fb29a 12302 return 0;
a361d84b
KY
12303}
12304
12305/* create playback/capture controls for input pins */
05f5f477 12306static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
12307 const struct auto_pin_cfg *cfg)
12308{
05f5f477 12309 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
12310}
12311
e9af4f36
TI
12312static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12313 hda_nid_t nid, int pin_type)
12314{
12315 int idx;
12316
12317 alc_set_pin_output(codec, nid, pin_type);
12318 if (nid == 0x14 || nid == 0x16)
12319 idx = 0;
12320 else
12321 idx = 1;
12322 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12323}
12324
12325static void alc268_auto_init_multi_out(struct hda_codec *codec)
12326{
12327 struct alc_spec *spec = codec->spec;
12328 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12329 if (nid) {
12330 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12331 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12332 }
12333}
12334
12335static void alc268_auto_init_hp_out(struct hda_codec *codec)
12336{
12337 struct alc_spec *spec = codec->spec;
12338 hda_nid_t pin;
12339
12340 pin = spec->autocfg.hp_pins[0];
12341 if (pin)
12342 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12343 pin = spec->autocfg.speaker_pins[0];
12344 if (pin)
12345 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12346}
12347
a361d84b
KY
12348static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12349{
12350 struct alc_spec *spec = codec->spec;
12351 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12352 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12353 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12354 unsigned int dac_vol1, dac_vol2;
12355
e9af4f36 12356 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
12357 snd_hda_codec_write(codec, speaker_nid, 0,
12358 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 12359 /* mute mixer inputs from 0x1d */
a361d84b
KY
12360 snd_hda_codec_write(codec, 0x0f, 0,
12361 AC_VERB_SET_AMP_GAIN_MUTE,
12362 AMP_IN_UNMUTE(1));
12363 snd_hda_codec_write(codec, 0x10, 0,
12364 AC_VERB_SET_AMP_GAIN_MUTE,
12365 AMP_IN_UNMUTE(1));
12366 } else {
e9af4f36 12367 /* unmute mixer inputs from 0x1d */
a361d84b
KY
12368 snd_hda_codec_write(codec, 0x0f, 0,
12369 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12370 snd_hda_codec_write(codec, 0x10, 0,
12371 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12372 }
12373
12374 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 12375 if (line_nid == 0x14)
a361d84b
KY
12376 dac_vol2 = AMP_OUT_ZERO;
12377 else if (line_nid == 0x15)
12378 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 12379 if (hp_nid == 0x14)
a361d84b
KY
12380 dac_vol2 = AMP_OUT_ZERO;
12381 else if (hp_nid == 0x15)
12382 dac_vol1 = AMP_OUT_ZERO;
12383 if (line_nid != 0x16 || hp_nid != 0x16 ||
12384 spec->autocfg.line_out_pins[1] != 0x16 ||
12385 spec->autocfg.line_out_pins[2] != 0x16)
12386 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12387
12388 snd_hda_codec_write(codec, 0x02, 0,
12389 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12390 snd_hda_codec_write(codec, 0x03, 0,
12391 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12392}
12393
def319f9 12394/* pcm configuration: identical with ALC880 */
a361d84b
KY
12395#define alc268_pcm_analog_playback alc880_pcm_analog_playback
12396#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 12397#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
12398#define alc268_pcm_digital_playback alc880_pcm_digital_playback
12399
12400/*
12401 * BIOS auto configuration
12402 */
12403static int alc268_parse_auto_config(struct hda_codec *codec)
12404{
12405 struct alc_spec *spec = codec->spec;
12406 int err;
12407 static hda_nid_t alc268_ignore[] = { 0 };
12408
12409 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12410 alc268_ignore);
12411 if (err < 0)
12412 return err;
7e0e44d4
TI
12413 if (!spec->autocfg.line_outs) {
12414 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12415 spec->multiout.max_channels = 2;
12416 spec->no_analog = 1;
12417 goto dig_only;
12418 }
a361d84b 12419 return 0; /* can't find valid BIOS pin config */
7e0e44d4 12420 }
a361d84b
KY
12421 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12422 if (err < 0)
12423 return err;
05f5f477 12424 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
12425 if (err < 0)
12426 return err;
12427
12428 spec->multiout.max_channels = 2;
12429
7e0e44d4 12430 dig_only:
a361d84b 12431 /* digital only support output */
7e0e44d4 12432 if (spec->autocfg.dig_outs) {
a361d84b 12433 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
12434 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12435 }
603c4019 12436 if (spec->kctls.list)
d88897ea 12437 add_mixer(spec, spec->kctls.list);
a361d84b 12438
892981ff 12439 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 12440 add_mixer(spec, alc268_beep_mixer);
aef9d318 12441
d88897ea 12442 add_verb(spec, alc268_volume_init_verbs);
5908589f 12443 spec->num_mux_defs = 2;
61b9b9b1 12444 spec->input_mux = &spec->private_imux[0];
a361d84b 12445
776e184e
TI
12446 err = alc_auto_add_mic_boost(codec);
12447 if (err < 0)
12448 return err;
12449
1d955ebd
TI
12450 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12451
a361d84b
KY
12452 return 1;
12453}
12454
a361d84b
KY
12455#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12456
12457/* init callback for auto-configuration model -- overriding the default init */
12458static void alc268_auto_init(struct hda_codec *codec)
12459{
f6c7e546 12460 struct alc_spec *spec = codec->spec;
a361d84b
KY
12461 alc268_auto_init_multi_out(codec);
12462 alc268_auto_init_hp_out(codec);
12463 alc268_auto_init_mono_speaker_out(codec);
12464 alc268_auto_init_analog_input(codec);
f6c7e546 12465 if (spec->unsol_event)
7fb0d78f 12466 alc_inithook(codec);
a361d84b
KY
12467}
12468
12469/*
12470 * configuration and preset
12471 */
12472static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 12473 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 12474 [ALC268_3ST] = "3stack",
983f8ae4 12475 [ALC268_TOSHIBA] = "toshiba",
d273809e 12476 [ALC268_ACER] = "acer",
c238b4f4 12477 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 12478 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 12479 [ALC268_DELL] = "dell",
f12462c5 12480 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
12481#ifdef CONFIG_SND_DEBUG
12482 [ALC268_TEST] = "test",
12483#endif
a361d84b
KY
12484 [ALC268_AUTO] = "auto",
12485};
12486
12487static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 12488 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 12489 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 12490 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 12491 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 12492 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
12493 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12494 ALC268_ACER_ASPIRE_ONE),
3866f0b0 12495 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
57d13927 12496 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
8871e5b9
TI
12497 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12498 ALC268_TOSHIBA),
a361d84b 12499 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 12500 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 12501 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 12502 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 12503 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 12504 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
12505 {}
12506};
12507
3abf2f36
TI
12508/* Toshiba laptops have no unique PCI SSID but only codec SSID */
12509static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12510 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
12511 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
12512 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12513 ALC268_TOSHIBA),
12514 {}
12515};
12516
a361d84b 12517static struct alc_config_preset alc268_presets[] = {
eb5a6621 12518 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
12519 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12520 alc268_capture_nosrc_mixer },
eb5a6621
HRK
12521 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12522 alc267_quanta_il1_verbs },
12523 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12524 .dac_nids = alc268_dac_nids,
12525 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12526 .adc_nids = alc268_adc_nids_alt,
12527 .hp_nid = 0x03,
12528 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12529 .channel_mode = alc268_modes,
4f5d1706
TI
12530 .unsol_event = alc_sku_unsol_event,
12531 .setup = alc267_quanta_il1_setup,
12532 .init_hook = alc_inithook,
eb5a6621 12533 },
a361d84b 12534 [ALC268_3ST] = {
aef9d318
TI
12535 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12536 alc268_beep_mixer },
a361d84b
KY
12537 .init_verbs = { alc268_base_init_verbs },
12538 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12539 .dac_nids = alc268_dac_nids,
12540 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12541 .adc_nids = alc268_adc_nids_alt,
e1406348 12542 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
12543 .hp_nid = 0x03,
12544 .dig_out_nid = ALC268_DIGOUT_NID,
12545 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12546 .channel_mode = alc268_modes,
12547 .input_mux = &alc268_capture_source,
12548 },
d1a991a6 12549 [ALC268_TOSHIBA] = {
42171c17 12550 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 12551 alc268_beep_mixer },
d273809e
TI
12552 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12553 alc268_toshiba_verbs },
d1a991a6
KY
12554 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12555 .dac_nids = alc268_dac_nids,
12556 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12557 .adc_nids = alc268_adc_nids_alt,
e1406348 12558 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
12559 .hp_nid = 0x03,
12560 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12561 .channel_mode = alc268_modes,
12562 .input_mux = &alc268_capture_source,
d273809e 12563 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
12564 .setup = alc268_toshiba_setup,
12565 .init_hook = alc268_toshiba_automute,
d273809e
TI
12566 },
12567 [ALC268_ACER] = {
fdbc6626 12568 .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer,
aef9d318 12569 alc268_beep_mixer },
d273809e
TI
12570 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12571 alc268_acer_verbs },
12572 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12573 .dac_nids = alc268_dac_nids,
12574 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12575 .adc_nids = alc268_adc_nids_alt,
e1406348 12576 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
12577 .hp_nid = 0x02,
12578 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12579 .channel_mode = alc268_modes,
0ccb541c 12580 .input_mux = &alc268_acer_capture_source,
d273809e 12581 .unsol_event = alc268_acer_unsol_event,
889c4395 12582 .init_hook = alc268_acer_init_hook,
d1a991a6 12583 },
c238b4f4
TI
12584 [ALC268_ACER_DMIC] = {
12585 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12586 alc268_beep_mixer },
12587 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12588 alc268_acer_verbs },
12589 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12590 .dac_nids = alc268_dac_nids,
12591 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12592 .adc_nids = alc268_adc_nids_alt,
12593 .capsrc_nids = alc268_capsrc_nids,
12594 .hp_nid = 0x02,
12595 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12596 .channel_mode = alc268_modes,
12597 .input_mux = &alc268_acer_dmic_capture_source,
12598 .unsol_event = alc268_acer_unsol_event,
12599 .init_hook = alc268_acer_init_hook,
12600 },
8ef355da
KY
12601 [ALC268_ACER_ASPIRE_ONE] = {
12602 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 12603 alc268_beep_mixer,
fdbc6626 12604 alc268_capture_nosrc_mixer },
8ef355da
KY
12605 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12606 alc268_acer_aspire_one_verbs },
12607 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12608 .dac_nids = alc268_dac_nids,
12609 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12610 .adc_nids = alc268_adc_nids_alt,
12611 .capsrc_nids = alc268_capsrc_nids,
12612 .hp_nid = 0x03,
12613 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12614 .channel_mode = alc268_modes,
8ef355da 12615 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 12616 .setup = alc268_acer_lc_setup,
8ef355da
KY
12617 .init_hook = alc268_acer_lc_init_hook,
12618 },
3866f0b0 12619 [ALC268_DELL] = {
fdbc6626
TI
12620 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12621 alc268_capture_nosrc_mixer },
3866f0b0
TI
12622 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12623 alc268_dell_verbs },
12624 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12625 .dac_nids = alc268_dac_nids,
fdbc6626
TI
12626 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12627 .adc_nids = alc268_adc_nids_alt,
12628 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
12629 .hp_nid = 0x02,
12630 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12631 .channel_mode = alc268_modes,
a9fd4f3f 12632 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
12633 .setup = alc268_dell_setup,
12634 .init_hook = alc_inithook,
3866f0b0 12635 },
f12462c5 12636 [ALC268_ZEPTO] = {
aef9d318
TI
12637 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12638 alc268_beep_mixer },
f12462c5
MT
12639 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12640 alc268_toshiba_verbs },
12641 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12642 .dac_nids = alc268_dac_nids,
12643 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12644 .adc_nids = alc268_adc_nids_alt,
e1406348 12645 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
12646 .hp_nid = 0x03,
12647 .dig_out_nid = ALC268_DIGOUT_NID,
12648 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12649 .channel_mode = alc268_modes,
12650 .input_mux = &alc268_capture_source,
4f5d1706
TI
12651 .setup = alc268_toshiba_setup,
12652 .init_hook = alc268_toshiba_automute,
f12462c5 12653 },
86c53bd2
JW
12654#ifdef CONFIG_SND_DEBUG
12655 [ALC268_TEST] = {
12656 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12657 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12658 alc268_volume_init_verbs },
12659 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12660 .dac_nids = alc268_dac_nids,
12661 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12662 .adc_nids = alc268_adc_nids_alt,
e1406348 12663 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
12664 .hp_nid = 0x03,
12665 .dig_out_nid = ALC268_DIGOUT_NID,
12666 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12667 .channel_mode = alc268_modes,
12668 .input_mux = &alc268_capture_source,
12669 },
12670#endif
a361d84b
KY
12671};
12672
12673static int patch_alc268(struct hda_codec *codec)
12674{
12675 struct alc_spec *spec;
12676 int board_config;
22971e3a 12677 int i, has_beep, err;
a361d84b
KY
12678
12679 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12680 if (spec == NULL)
12681 return -ENOMEM;
12682
12683 codec->spec = spec;
12684
12685 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12686 alc268_models,
12687 alc268_cfg_tbl);
12688
3abf2f36
TI
12689 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
12690 board_config = snd_hda_check_board_codec_sid_config(codec,
12691 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12692
a361d84b 12693 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
12694 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12695 codec->chip_name);
a361d84b
KY
12696 board_config = ALC268_AUTO;
12697 }
12698
12699 if (board_config == ALC268_AUTO) {
12700 /* automatic parse from the BIOS config */
12701 err = alc268_parse_auto_config(codec);
12702 if (err < 0) {
12703 alc_free(codec);
12704 return err;
12705 } else if (!err) {
12706 printk(KERN_INFO
12707 "hda_codec: Cannot set up configuration "
12708 "from BIOS. Using base mode...\n");
12709 board_config = ALC268_3ST;
12710 }
12711 }
12712
12713 if (board_config != ALC268_AUTO)
e9c364c0 12714 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 12715
a361d84b
KY
12716 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12717 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 12718 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 12719
a361d84b
KY
12720 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12721
22971e3a
TI
12722 has_beep = 0;
12723 for (i = 0; i < spec->num_mixers; i++) {
12724 if (spec->mixers[i] == alc268_beep_mixer) {
12725 has_beep = 1;
12726 break;
12727 }
12728 }
12729
12730 if (has_beep) {
12731 err = snd_hda_attach_beep_device(codec, 0x1);
12732 if (err < 0) {
12733 alc_free(codec);
12734 return err;
12735 }
12736 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12737 /* override the amp caps for beep generator */
12738 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
12739 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12740 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12741 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12742 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 12743 }
aef9d318 12744
7e0e44d4 12745 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
12746 /* check whether NID 0x07 is valid */
12747 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 12748 int i;
3866f0b0
TI
12749
12750 /* get type */
a22d543a 12751 wcap = get_wcaps_type(wcap);
fdbc6626
TI
12752 if (spec->auto_mic ||
12753 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
12754 spec->adc_nids = alc268_adc_nids_alt;
12755 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
fdbc6626
TI
12756 if (spec->auto_mic || spec->input_mux->num_items == 1)
12757 add_mixer(spec, alc268_capture_nosrc_mixer);
12758 else
12759 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
12760 } else {
12761 spec->adc_nids = alc268_adc_nids;
12762 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 12763 add_mixer(spec, alc268_capture_mixer);
a361d84b 12764 }
e1406348 12765 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
12766 /* set default input source */
12767 for (i = 0; i < spec->num_adc_nids; i++)
12768 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12769 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
12770 i < spec->num_mux_defs ?
12771 spec->input_mux[i].items[0].index :
85860c06 12772 spec->input_mux->items[0].index);
a361d84b 12773 }
2134ea4f
TI
12774
12775 spec->vmaster_nid = 0x02;
12776
a361d84b
KY
12777 codec->patch_ops = alc_patch_ops;
12778 if (board_config == ALC268_AUTO)
12779 spec->init_hook = alc268_auto_init;
ea1fb29a 12780
daead538
TI
12781 codec->proc_widget_hook = print_realtek_coef;
12782
a361d84b
KY
12783 return 0;
12784}
12785
f6a92248
KY
12786/*
12787 * ALC269 channel source setting (2 channel)
12788 */
12789#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12790
12791#define alc269_dac_nids alc260_dac_nids
12792
12793static hda_nid_t alc269_adc_nids[1] = {
12794 /* ADC1 */
f53281e6
KY
12795 0x08,
12796};
12797
e01bf509
TI
12798static hda_nid_t alc269_capsrc_nids[1] = {
12799 0x23,
12800};
12801
12802/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12803 * not a mux!
12804 */
12805
f6a92248
KY
12806#define alc269_modes alc260_modes
12807#define alc269_capture_source alc880_lg_lw_capture_source
12808
12809static struct snd_kcontrol_new alc269_base_mixer[] = {
12810 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12811 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12812 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12813 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12816 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12817 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12818 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12819 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12821 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12822 { } /* end */
12823};
12824
60db6b53
KY
12825static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12826 /* output mixer control */
12827 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12828 {
12829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12830 .name = "Master Playback Switch",
12831 .info = snd_hda_mixer_amp_switch_info,
12832 .get = snd_hda_mixer_amp_switch_get,
12833 .put = alc268_acer_master_sw_put,
12834 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12835 },
12836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12838 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12839 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12840 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12841 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
12842 { }
12843};
12844
64154835
TV
12845static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12846 /* output mixer control */
12847 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12848 {
12849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12850 .name = "Master Playback Switch",
12851 .info = snd_hda_mixer_amp_switch_info,
12852 .get = snd_hda_mixer_amp_switch_get,
12853 .put = alc268_acer_master_sw_put,
12854 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12855 },
12856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12858 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12859 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12860 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12861 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12862 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12863 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12864 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
12865 { }
12866};
12867
f53281e6 12868static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
aa202455 12869 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 12870 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 12871 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 12872 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
12873 { } /* end */
12874};
12875
f53281e6
KY
12876/* capture mixer elements */
12877static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12878 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12879 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
12880 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12881 { } /* end */
12882};
12883
12884/* FSC amilo */
aa202455 12885#define alc269_fujitsu_mixer alc269_eeepc_mixer
f53281e6 12886
60db6b53
KY
12887static struct hda_verb alc269_quanta_fl1_verbs[] = {
12888 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12889 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12890 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12891 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12892 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12893 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12894 { }
12895};
f6a92248 12896
64154835
TV
12897static struct hda_verb alc269_lifebook_verbs[] = {
12898 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12899 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12900 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12902 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12903 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12905 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12906 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12907 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12908 { }
12909};
12910
60db6b53
KY
12911/* toggle speaker-output according to the hp-jack state */
12912static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12913{
12914 unsigned int present;
12915 unsigned char bits;
f6a92248 12916
60db6b53
KY
12917 present = snd_hda_codec_read(codec, 0x15, 0,
12918 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12919 bits = present ? AMP_IN_MUTE(0) : 0;
12920 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12921 AMP_IN_MUTE(0), bits);
12922 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12923 AMP_IN_MUTE(0), bits);
f6a92248 12924
60db6b53
KY
12925 snd_hda_codec_write(codec, 0x20, 0,
12926 AC_VERB_SET_COEF_INDEX, 0x0c);
12927 snd_hda_codec_write(codec, 0x20, 0,
12928 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 12929
60db6b53
KY
12930 snd_hda_codec_write(codec, 0x20, 0,
12931 AC_VERB_SET_COEF_INDEX, 0x0c);
12932 snd_hda_codec_write(codec, 0x20, 0,
12933 AC_VERB_SET_PROC_COEF, 0x480);
12934}
f6a92248 12935
64154835
TV
12936/* toggle speaker-output according to the hp-jacks state */
12937static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12938{
12939 unsigned int present;
12940 unsigned char bits;
12941
12942 /* Check laptop headphone socket */
12943 present = snd_hda_codec_read(codec, 0x15, 0,
12944 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12945
12946 /* Check port replicator headphone socket */
12947 present |= snd_hda_codec_read(codec, 0x1a, 0,
12948 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12949
12950 bits = present ? AMP_IN_MUTE(0) : 0;
12951 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12952 AMP_IN_MUTE(0), bits);
12953 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12954 AMP_IN_MUTE(0), bits);
12955
12956 snd_hda_codec_write(codec, 0x20, 0,
12957 AC_VERB_SET_COEF_INDEX, 0x0c);
12958 snd_hda_codec_write(codec, 0x20, 0,
12959 AC_VERB_SET_PROC_COEF, 0x680);
12960
12961 snd_hda_codec_write(codec, 0x20, 0,
12962 AC_VERB_SET_COEF_INDEX, 0x0c);
12963 snd_hda_codec_write(codec, 0x20, 0,
12964 AC_VERB_SET_PROC_COEF, 0x480);
12965}
12966
64154835
TV
12967static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12968{
12969 unsigned int present_laptop;
12970 unsigned int present_dock;
12971
12972 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12973 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12974
12975 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12976 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12977
12978 /* Laptop mic port overrides dock mic port, design decision */
12979 if (present_dock)
12980 snd_hda_codec_write(codec, 0x23, 0,
12981 AC_VERB_SET_CONNECT_SEL, 0x3);
12982 if (present_laptop)
12983 snd_hda_codec_write(codec, 0x23, 0,
12984 AC_VERB_SET_CONNECT_SEL, 0x0);
12985 if (!present_dock && !present_laptop)
12986 snd_hda_codec_write(codec, 0x23, 0,
12987 AC_VERB_SET_CONNECT_SEL, 0x1);
12988}
12989
60db6b53
KY
12990static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12991 unsigned int res)
12992{
4f5d1706
TI
12993 switch (res >> 26) {
12994 case ALC880_HP_EVENT:
60db6b53 12995 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
12996 break;
12997 case ALC880_MIC_EVENT:
12998 alc_mic_automute(codec);
12999 break;
13000 }
60db6b53 13001}
f6a92248 13002
64154835
TV
13003static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13004 unsigned int res)
13005{
13006 if ((res >> 26) == ALC880_HP_EVENT)
13007 alc269_lifebook_speaker_automute(codec);
13008 if ((res >> 26) == ALC880_MIC_EVENT)
13009 alc269_lifebook_mic_autoswitch(codec);
13010}
13011
4f5d1706
TI
13012static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13013{
13014 struct alc_spec *spec = codec->spec;
13015 spec->ext_mic.pin = 0x18;
13016 spec->ext_mic.mux_idx = 0;
13017 spec->int_mic.pin = 0x19;
13018 spec->int_mic.mux_idx = 1;
13019 spec->auto_mic = 1;
13020}
13021
60db6b53
KY
13022static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13023{
13024 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13025 alc_mic_automute(codec);
60db6b53 13026}
f6a92248 13027
64154835
TV
13028static void alc269_lifebook_init_hook(struct hda_codec *codec)
13029{
13030 alc269_lifebook_speaker_automute(codec);
13031 alc269_lifebook_mic_autoswitch(codec);
13032}
13033
f53281e6
KY
13034static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13035 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13036 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13037 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13039 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13040 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13041 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13042 {}
13043};
13044
13045static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13046 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13047 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13048 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13049 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13050 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13051 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13052 {}
13053};
13054
13055/* toggle speaker-output according to the hp-jack state */
13056static void alc269_speaker_automute(struct hda_codec *codec)
13057{
13058 unsigned int present;
60db6b53 13059 unsigned char bits;
f53281e6
KY
13060
13061 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 13062 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
13063 bits = present ? AMP_IN_MUTE(0) : 0;
13064 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 13065 AMP_IN_MUTE(0), bits);
f53281e6 13066 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 13067 AMP_IN_MUTE(0), bits);
f53281e6
KY
13068}
13069
f53281e6 13070/* unsolicited event for HP jack sensing */
4f5d1706 13071static void alc269_eeepc_unsol_event(struct hda_codec *codec,
60db6b53 13072 unsigned int res)
f53281e6 13073{
4f5d1706
TI
13074 switch (res >> 26) {
13075 case ALC880_HP_EVENT:
f53281e6 13076 alc269_speaker_automute(codec);
4f5d1706
TI
13077 break;
13078 case ALC880_MIC_EVENT:
13079 alc_mic_automute(codec);
13080 break;
13081 }
f53281e6
KY
13082}
13083
4f5d1706 13084static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
f53281e6 13085{
4f5d1706
TI
13086 struct alc_spec *spec = codec->spec;
13087 spec->ext_mic.pin = 0x18;
13088 spec->ext_mic.mux_idx = 0;
13089 spec->int_mic.pin = 0x12;
13090 spec->int_mic.mux_idx = 5;
13091 spec->auto_mic = 1;
f53281e6
KY
13092}
13093
4f5d1706 13094static void alc269_eeepc_amic_setup(struct hda_codec *codec)
f53281e6 13095{
4f5d1706
TI
13096 struct alc_spec *spec = codec->spec;
13097 spec->ext_mic.pin = 0x18;
13098 spec->ext_mic.mux_idx = 0;
13099 spec->int_mic.pin = 0x19;
13100 spec->int_mic.mux_idx = 1;
13101 spec->auto_mic = 1;
f53281e6
KY
13102}
13103
4f5d1706 13104static void alc269_eeepc_inithook(struct hda_codec *codec)
f53281e6
KY
13105{
13106 alc269_speaker_automute(codec);
4f5d1706 13107 alc_mic_automute(codec);
f53281e6
KY
13108}
13109
60db6b53
KY
13110/*
13111 * generic initialization of ADC, input mixers and output mixers
13112 */
13113static struct hda_verb alc269_init_verbs[] = {
13114 /*
13115 * Unmute ADC0 and set the default input to mic-in
13116 */
13117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13118
13119 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13120 * analog-loopback mixer widget
13121 * Note: PASD motherboards uses the Line In 2 as the input for
13122 * front panel mic (mic 2)
13123 */
13124 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13125 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13126 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13127 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13128 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13129 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13130
13131 /*
13132 * Set up output mixers (0x0c - 0x0e)
13133 */
13134 /* set vol=0 to output mixers */
13135 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13136 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13137
13138 /* set up input amps for analog loopback */
13139 /* Amp Indices: DAC = 0, mixer = 1 */
13140 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13141 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13142 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13143 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13144 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13145 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13146
13147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13149 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13151 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13152 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13154
13155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13157 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13159 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13160 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13161 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13162
13163 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13164 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13165
13166 /* FIXME: use matrix-type input source selection */
13167 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13168 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13169 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13170 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13171 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13172 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13173
13174 /* set EAPD */
13175 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13176 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13177 { }
13178};
13179
9d0b71b1
TI
13180#define alc269_auto_create_multi_out_ctls \
13181 alc268_auto_create_multi_out_ctls
05f5f477
TI
13182#define alc269_auto_create_input_ctls \
13183 alc268_auto_create_input_ctls
f6a92248
KY
13184
13185#ifdef CONFIG_SND_HDA_POWER_SAVE
13186#define alc269_loopbacks alc880_loopbacks
13187#endif
13188
def319f9 13189/* pcm configuration: identical with ALC880 */
f6a92248
KY
13190#define alc269_pcm_analog_playback alc880_pcm_analog_playback
13191#define alc269_pcm_analog_capture alc880_pcm_analog_capture
13192#define alc269_pcm_digital_playback alc880_pcm_digital_playback
13193#define alc269_pcm_digital_capture alc880_pcm_digital_capture
13194
f03d3115
TI
13195static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13196 .substreams = 1,
13197 .channels_min = 2,
13198 .channels_max = 8,
13199 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13200 /* NID is set in alc_build_pcms */
13201 .ops = {
13202 .open = alc880_playback_pcm_open,
13203 .prepare = alc880_playback_pcm_prepare,
13204 .cleanup = alc880_playback_pcm_cleanup
13205 },
13206};
13207
13208static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13209 .substreams = 1,
13210 .channels_min = 2,
13211 .channels_max = 2,
13212 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13213 /* NID is set in alc_build_pcms */
13214};
13215
f6a92248
KY
13216/*
13217 * BIOS auto configuration
13218 */
13219static int alc269_parse_auto_config(struct hda_codec *codec)
13220{
13221 struct alc_spec *spec = codec->spec;
cfb9fb55 13222 int err;
f6a92248
KY
13223 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13224
13225 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13226 alc269_ignore);
13227 if (err < 0)
13228 return err;
13229
13230 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13231 if (err < 0)
13232 return err;
05f5f477 13233 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
13234 if (err < 0)
13235 return err;
13236
13237 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13238
0852d7a6 13239 if (spec->autocfg.dig_outs)
f6a92248
KY
13240 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13241
603c4019 13242 if (spec->kctls.list)
d88897ea 13243 add_mixer(spec, spec->kctls.list);
f6a92248 13244
d88897ea 13245 add_verb(spec, alc269_init_verbs);
f6a92248 13246 spec->num_mux_defs = 1;
61b9b9b1 13247 spec->input_mux = &spec->private_imux[0];
e01bf509
TI
13248 /* set default input source */
13249 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13250 0, AC_VERB_SET_CONNECT_SEL,
13251 spec->input_mux->items[0].index);
f6a92248
KY
13252
13253 err = alc_auto_add_mic_boost(codec);
13254 if (err < 0)
13255 return err;
13256
7e0e44d4 13257 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13258 set_capture_mixer(codec);
f53281e6 13259
1d955ebd
TI
13260 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13261
f6a92248
KY
13262 return 1;
13263}
13264
e9af4f36
TI
13265#define alc269_auto_init_multi_out alc268_auto_init_multi_out
13266#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
13267#define alc269_auto_init_analog_input alc882_auto_init_analog_input
13268
13269
13270/* init callback for auto-configuration model -- overriding the default init */
13271static void alc269_auto_init(struct hda_codec *codec)
13272{
f6c7e546 13273 struct alc_spec *spec = codec->spec;
f6a92248
KY
13274 alc269_auto_init_multi_out(codec);
13275 alc269_auto_init_hp_out(codec);
13276 alc269_auto_init_analog_input(codec);
f6c7e546 13277 if (spec->unsol_event)
7fb0d78f 13278 alc_inithook(codec);
f6a92248
KY
13279}
13280
13281/*
13282 * configuration and preset
13283 */
13284static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 13285 [ALC269_BASIC] = "basic",
2922c9af
TI
13286 [ALC269_QUANTA_FL1] = "quanta",
13287 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
26f5df26 13288 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
64154835
TV
13289 [ALC269_FUJITSU] = "fujitsu",
13290 [ALC269_LIFEBOOK] = "lifebook"
f6a92248
KY
13291};
13292
13293static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 13294 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
13295 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13296 ALC269_ASUS_EEEPC_P703),
622e84cd
KY
13297 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13298 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13299 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13300 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13301 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13302 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
f53281e6
KY
13303 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13304 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
13305 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13306 ALC269_ASUS_EEEPC_P901),
622e84cd 13307 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
26f5df26 13308 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
64154835 13309 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
f6a92248
KY
13310 {}
13311};
13312
13313static struct alc_config_preset alc269_presets[] = {
13314 [ALC269_BASIC] = {
f9e336f6 13315 .mixers = { alc269_base_mixer },
f6a92248
KY
13316 .init_verbs = { alc269_init_verbs },
13317 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13318 .dac_nids = alc269_dac_nids,
13319 .hp_nid = 0x03,
13320 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13321 .channel_mode = alc269_modes,
13322 .input_mux = &alc269_capture_source,
13323 },
60db6b53
KY
13324 [ALC269_QUANTA_FL1] = {
13325 .mixers = { alc269_quanta_fl1_mixer },
13326 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13327 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13328 .dac_nids = alc269_dac_nids,
13329 .hp_nid = 0x03,
13330 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13331 .channel_mode = alc269_modes,
13332 .input_mux = &alc269_capture_source,
13333 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 13334 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
13335 .init_hook = alc269_quanta_fl1_init_hook,
13336 },
f53281e6 13337 [ALC269_ASUS_EEEPC_P703] = {
f9e336f6
TI
13338 .mixers = { alc269_eeepc_mixer },
13339 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13340 .init_verbs = { alc269_init_verbs,
13341 alc269_eeepc_amic_init_verbs },
13342 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13343 .dac_nids = alc269_dac_nids,
13344 .hp_nid = 0x03,
13345 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13346 .channel_mode = alc269_modes,
4f5d1706
TI
13347 .unsol_event = alc269_eeepc_unsol_event,
13348 .setup = alc269_eeepc_amic_setup,
13349 .init_hook = alc269_eeepc_inithook,
f53281e6
KY
13350 },
13351 [ALC269_ASUS_EEEPC_P901] = {
f9e336f6
TI
13352 .mixers = { alc269_eeepc_mixer },
13353 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13354 .init_verbs = { alc269_init_verbs,
13355 alc269_eeepc_dmic_init_verbs },
13356 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13357 .dac_nids = alc269_dac_nids,
13358 .hp_nid = 0x03,
13359 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13360 .channel_mode = alc269_modes,
4f5d1706
TI
13361 .unsol_event = alc269_eeepc_unsol_event,
13362 .setup = alc269_eeepc_dmic_setup,
13363 .init_hook = alc269_eeepc_inithook,
f53281e6 13364 },
26f5df26 13365 [ALC269_FUJITSU] = {
45bdd1c1 13366 .mixers = { alc269_fujitsu_mixer },
26f5df26
TI
13367 .cap_mixer = alc269_epc_capture_mixer,
13368 .init_verbs = { alc269_init_verbs,
13369 alc269_eeepc_dmic_init_verbs },
13370 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13371 .dac_nids = alc269_dac_nids,
13372 .hp_nid = 0x03,
13373 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13374 .channel_mode = alc269_modes,
4f5d1706
TI
13375 .unsol_event = alc269_eeepc_unsol_event,
13376 .setup = alc269_eeepc_dmic_setup,
13377 .init_hook = alc269_eeepc_inithook,
26f5df26 13378 },
64154835
TV
13379 [ALC269_LIFEBOOK] = {
13380 .mixers = { alc269_lifebook_mixer },
13381 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13382 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13383 .dac_nids = alc269_dac_nids,
13384 .hp_nid = 0x03,
13385 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13386 .channel_mode = alc269_modes,
13387 .input_mux = &alc269_capture_source,
13388 .unsol_event = alc269_lifebook_unsol_event,
13389 .init_hook = alc269_lifebook_init_hook,
13390 },
f6a92248
KY
13391};
13392
13393static int patch_alc269(struct hda_codec *codec)
13394{
13395 struct alc_spec *spec;
13396 int board_config;
13397 int err;
13398
13399 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13400 if (spec == NULL)
13401 return -ENOMEM;
13402
13403 codec->spec = spec;
13404
2c3bf9ab
TI
13405 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13406
f6a92248
KY
13407 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13408 alc269_models,
13409 alc269_cfg_tbl);
13410
13411 if (board_config < 0) {
9a11f1aa
TI
13412 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13413 codec->chip_name);
f6a92248
KY
13414 board_config = ALC269_AUTO;
13415 }
13416
13417 if (board_config == ALC269_AUTO) {
13418 /* automatic parse from the BIOS config */
13419 err = alc269_parse_auto_config(codec);
13420 if (err < 0) {
13421 alc_free(codec);
13422 return err;
13423 } else if (!err) {
13424 printk(KERN_INFO
13425 "hda_codec: Cannot set up configuration "
13426 "from BIOS. Using base mode...\n");
13427 board_config = ALC269_BASIC;
13428 }
13429 }
13430
680cd536
KK
13431 err = snd_hda_attach_beep_device(codec, 0x1);
13432 if (err < 0) {
13433 alc_free(codec);
13434 return err;
13435 }
13436
f6a92248 13437 if (board_config != ALC269_AUTO)
e9c364c0 13438 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 13439
f03d3115
TI
13440 if (codec->subsystem_id == 0x17aa3bf8) {
13441 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13442 * fix the sample rate of analog I/O to 44.1kHz
13443 */
13444 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13445 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13446 } else {
13447 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13448 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13449 }
f6a92248
KY
13450 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13451 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13452
13453 spec->adc_nids = alc269_adc_nids;
13454 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 13455 spec->capsrc_nids = alc269_capsrc_nids;
f9e336f6 13456 if (!spec->cap_mixer)
b59bdf3b 13457 set_capture_mixer(codec);
45bdd1c1 13458 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 13459
100d5eb3
TI
13460 spec->vmaster_nid = 0x02;
13461
f6a92248
KY
13462 codec->patch_ops = alc_patch_ops;
13463 if (board_config == ALC269_AUTO)
13464 spec->init_hook = alc269_auto_init;
13465#ifdef CONFIG_SND_HDA_POWER_SAVE
13466 if (!spec->loopback.amplist)
13467 spec->loopback.amplist = alc269_loopbacks;
13468#endif
daead538 13469 codec->proc_widget_hook = print_realtek_coef;
f6a92248
KY
13470
13471 return 0;
13472}
13473
df694daa
KY
13474/*
13475 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13476 */
13477
13478/*
13479 * set the path ways for 2 channel output
13480 * need to set the codec line out and mic 1 pin widgets to inputs
13481 */
13482static struct hda_verb alc861_threestack_ch2_init[] = {
13483 /* set pin widget 1Ah (line in) for input */
13484 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13485 /* set pin widget 18h (mic1/2) for input, for mic also enable
13486 * the vref
13487 */
df694daa
KY
13488 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13489
9c7f852e
TI
13490 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13491#if 0
13492 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13493 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13494#endif
df694daa
KY
13495 { } /* end */
13496};
13497/*
13498 * 6ch mode
13499 * need to set the codec line out and mic 1 pin widgets to outputs
13500 */
13501static struct hda_verb alc861_threestack_ch6_init[] = {
13502 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13503 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13504 /* set pin widget 18h (mic1) for output (CLFE)*/
13505 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13506
13507 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 13508 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 13509
9c7f852e
TI
13510 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13511#if 0
13512 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13513 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13514#endif
df694daa
KY
13515 { } /* end */
13516};
13517
13518static struct hda_channel_mode alc861_threestack_modes[2] = {
13519 { 2, alc861_threestack_ch2_init },
13520 { 6, alc861_threestack_ch6_init },
13521};
22309c3e
TI
13522/* Set mic1 as input and unmute the mixer */
13523static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13524 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13525 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13526 { } /* end */
13527};
13528/* Set mic1 as output and mute mixer */
13529static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13530 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13531 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13532 { } /* end */
13533};
13534
13535static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13536 { 2, alc861_uniwill_m31_ch2_init },
13537 { 4, alc861_uniwill_m31_ch4_init },
13538};
df694daa 13539
7cdbff94
MD
13540/* Set mic1 and line-in as input and unmute the mixer */
13541static struct hda_verb alc861_asus_ch2_init[] = {
13542 /* set pin widget 1Ah (line in) for input */
13543 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13544 /* set pin widget 18h (mic1/2) for input, for mic also enable
13545 * the vref
13546 */
7cdbff94
MD
13547 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13548
13549 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13550#if 0
13551 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13552 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13553#endif
13554 { } /* end */
13555};
13556/* Set mic1 nad line-in as output and mute mixer */
13557static struct hda_verb alc861_asus_ch6_init[] = {
13558 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13559 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13560 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13561 /* set pin widget 18h (mic1) for output (CLFE)*/
13562 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13563 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13564 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13565 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13566
13567 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13568#if 0
13569 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13570 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13571#endif
13572 { } /* end */
13573};
13574
13575static struct hda_channel_mode alc861_asus_modes[2] = {
13576 { 2, alc861_asus_ch2_init },
13577 { 6, alc861_asus_ch6_init },
13578};
13579
df694daa
KY
13580/* patch-ALC861 */
13581
13582static struct snd_kcontrol_new alc861_base_mixer[] = {
13583 /* output mixer control */
13584 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13585 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13586 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13587 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13588 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13589
13590 /*Input mixer control */
13591 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13592 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13593 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13594 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13595 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13596 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13598 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13599 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13600 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13601
df694daa
KY
13602 { } /* end */
13603};
13604
13605static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13606 /* output mixer control */
13607 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13608 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13609 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13610 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13611 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13612
13613 /* Input mixer control */
13614 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13615 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13616 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13617 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13618 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13619 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13621 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13622 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13624
df694daa
KY
13625 {
13626 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13627 .name = "Channel Mode",
13628 .info = alc_ch_mode_info,
13629 .get = alc_ch_mode_get,
13630 .put = alc_ch_mode_put,
13631 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13632 },
13633 { } /* end */
a53d1aec
TD
13634};
13635
d1d985f0 13636static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
13637 /* output mixer control */
13638 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13640 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 13641
a53d1aec 13642 { } /* end */
f12ab1e0 13643};
a53d1aec 13644
22309c3e
TI
13645static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13646 /* output mixer control */
13647 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13648 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13649 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13650 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13651 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13652
13653 /* Input mixer control */
13654 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13655 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13656 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13657 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13658 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13659 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13661 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13662 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13663 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13664
22309c3e
TI
13665 {
13666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13667 .name = "Channel Mode",
13668 .info = alc_ch_mode_info,
13669 .get = alc_ch_mode_get,
13670 .put = alc_ch_mode_put,
13671 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13672 },
13673 { } /* end */
f12ab1e0 13674};
7cdbff94
MD
13675
13676static struct snd_kcontrol_new alc861_asus_mixer[] = {
13677 /* output mixer control */
13678 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13679 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13680 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13681 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13682 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13683
13684 /* Input mixer control */
13685 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13686 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13687 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13688 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13689 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13690 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13692 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
13694 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13695
7cdbff94
MD
13696 {
13697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13698 .name = "Channel Mode",
13699 .info = alc_ch_mode_info,
13700 .get = alc_ch_mode_get,
13701 .put = alc_ch_mode_put,
13702 .private_value = ARRAY_SIZE(alc861_asus_modes),
13703 },
13704 { }
56bb0cab
TI
13705};
13706
13707/* additional mixer */
d1d985f0 13708static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
13709 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13710 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
13711 { }
13712};
7cdbff94 13713
df694daa
KY
13714/*
13715 * generic initialization of ADC, input mixers and output mixers
13716 */
13717static struct hda_verb alc861_base_init_verbs[] = {
13718 /*
13719 * Unmute ADC0 and set the default input to mic-in
13720 */
13721 /* port-A for surround (rear panel) */
13722 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13723 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13724 /* port-B for mic-in (rear panel) with vref */
13725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13726 /* port-C for line-in (rear panel) */
13727 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13728 /* port-D for Front */
13729 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13730 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13731 /* port-E for HP out (front panel) */
13732 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13733 /* route front PCM to HP */
9dece1d7 13734 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13735 /* port-F for mic-in (front panel) with vref */
13736 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13737 /* port-G for CLFE (rear panel) */
13738 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13739 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13740 /* port-H for side (rear panel) */
13741 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13742 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13743 /* CD-in */
13744 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13745 /* route front mic to ADC1*/
13746 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13748
df694daa
KY
13749 /* Unmute DAC0~3 & spdif out*/
13750 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13751 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13752 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13753 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13755
df694daa
KY
13756 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13757 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13758 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13759 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13760 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13761
df694daa
KY
13762 /* Unmute Stereo Mixer 15 */
13763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13767
13768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13769 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13772 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13773 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13776 /* hp used DAC 3 (Front) */
13777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13778 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13779
13780 { }
13781};
13782
13783static struct hda_verb alc861_threestack_init_verbs[] = {
13784 /*
13785 * Unmute ADC0 and set the default input to mic-in
13786 */
13787 /* port-A for surround (rear panel) */
13788 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13789 /* port-B for mic-in (rear panel) with vref */
13790 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13791 /* port-C for line-in (rear panel) */
13792 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13793 /* port-D for Front */
13794 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13795 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13796 /* port-E for HP out (front panel) */
13797 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13798 /* route front PCM to HP */
9dece1d7 13799 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13800 /* port-F for mic-in (front panel) with vref */
13801 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13802 /* port-G for CLFE (rear panel) */
13803 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13804 /* port-H for side (rear panel) */
13805 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13806 /* CD-in */
13807 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13808 /* route front mic to ADC1*/
13809 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13810 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13811 /* Unmute DAC0~3 & spdif out*/
13812 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13813 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13814 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13815 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13817
df694daa
KY
13818 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13819 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13820 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13821 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13822 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13823
df694daa
KY
13824 /* Unmute Stereo Mixer 15 */
13825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13829
13830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13838 /* hp used DAC 3 (Front) */
13839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13841 { }
13842};
22309c3e
TI
13843
13844static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13845 /*
13846 * Unmute ADC0 and set the default input to mic-in
13847 */
13848 /* port-A for surround (rear panel) */
13849 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13850 /* port-B for mic-in (rear panel) with vref */
13851 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13852 /* port-C for line-in (rear panel) */
13853 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13854 /* port-D for Front */
13855 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13856 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13857 /* port-E for HP out (front panel) */
f12ab1e0
TI
13858 /* this has to be set to VREF80 */
13859 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 13860 /* route front PCM to HP */
9dece1d7 13861 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
13862 /* port-F for mic-in (front panel) with vref */
13863 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13864 /* port-G for CLFE (rear panel) */
13865 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13866 /* port-H for side (rear panel) */
13867 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13868 /* CD-in */
13869 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13870 /* route front mic to ADC1*/
13871 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13872 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13873 /* Unmute DAC0~3 & spdif out*/
13874 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13875 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13876 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13877 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13878 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13879
22309c3e
TI
13880 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13881 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13882 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13883 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13884 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13885
22309c3e
TI
13886 /* Unmute Stereo Mixer 15 */
13887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13888 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13890 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
13891
13892 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13893 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13894 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13895 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13896 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13899 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13900 /* hp used DAC 3 (Front) */
13901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
13902 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13903 { }
13904};
13905
7cdbff94
MD
13906static struct hda_verb alc861_asus_init_verbs[] = {
13907 /*
13908 * Unmute ADC0 and set the default input to mic-in
13909 */
f12ab1e0
TI
13910 /* port-A for surround (rear panel)
13911 * according to codec#0 this is the HP jack
13912 */
7cdbff94
MD
13913 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13914 /* route front PCM to HP */
13915 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13916 /* port-B for mic-in (rear panel) with vref */
13917 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13918 /* port-C for line-in (rear panel) */
13919 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13920 /* port-D for Front */
13921 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13922 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13923 /* port-E for HP out (front panel) */
f12ab1e0
TI
13924 /* this has to be set to VREF80 */
13925 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 13926 /* route front PCM to HP */
9dece1d7 13927 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
13928 /* port-F for mic-in (front panel) with vref */
13929 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13930 /* port-G for CLFE (rear panel) */
13931 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13932 /* port-H for side (rear panel) */
13933 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13934 /* CD-in */
13935 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13936 /* route front mic to ADC1*/
13937 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13938 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13939 /* Unmute DAC0~3 & spdif out*/
13940 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13941 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13942 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13943 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13945 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13946 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13947 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13948 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13949 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13950
7cdbff94
MD
13951 /* Unmute Stereo Mixer 15 */
13952 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13953 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13956
13957 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13958 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13959 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13960 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13961 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13962 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13963 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13964 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13965 /* hp used DAC 3 (Front) */
13966 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13967 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13968 { }
13969};
13970
56bb0cab
TI
13971/* additional init verbs for ASUS laptops */
13972static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13973 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13974 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13975 { }
13976};
7cdbff94 13977
df694daa
KY
13978/*
13979 * generic initialization of ADC, input mixers and output mixers
13980 */
13981static struct hda_verb alc861_auto_init_verbs[] = {
13982 /*
13983 * Unmute ADC0 and set the default input to mic-in
13984 */
f12ab1e0 13985 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13987
df694daa
KY
13988 /* Unmute DAC0~3 & spdif out*/
13989 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13990 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13991 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13992 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13994
df694daa
KY
13995 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13996 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13997 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13998 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13999 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14000
df694daa
KY
14001 /* Unmute Stereo Mixer 15 */
14002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14004 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14006
1c20930a
TI
14007 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14008 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14009 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14010 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14012 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14014 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
14015
14016 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14017 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14018 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14019 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
14020 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14021 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14022 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14023 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 14024
f12ab1e0 14025 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
14026
14027 { }
14028};
14029
a53d1aec
TD
14030static struct hda_verb alc861_toshiba_init_verbs[] = {
14031 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 14032
a53d1aec
TD
14033 { }
14034};
14035
14036/* toggle speaker-output according to the hp-jack state */
14037static void alc861_toshiba_automute(struct hda_codec *codec)
14038{
14039 unsigned int present;
14040
14041 present = snd_hda_codec_read(codec, 0x0f, 0,
14042 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14043 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14044 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14045 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14046 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
14047}
14048
14049static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14050 unsigned int res)
14051{
a53d1aec
TD
14052 if ((res >> 26) == ALC880_HP_EVENT)
14053 alc861_toshiba_automute(codec);
14054}
14055
def319f9 14056/* pcm configuration: identical with ALC880 */
df694daa
KY
14057#define alc861_pcm_analog_playback alc880_pcm_analog_playback
14058#define alc861_pcm_analog_capture alc880_pcm_analog_capture
14059#define alc861_pcm_digital_playback alc880_pcm_digital_playback
14060#define alc861_pcm_digital_capture alc880_pcm_digital_capture
14061
14062
14063#define ALC861_DIGOUT_NID 0x07
14064
14065static struct hda_channel_mode alc861_8ch_modes[1] = {
14066 { 8, NULL }
14067};
14068
14069static hda_nid_t alc861_dac_nids[4] = {
14070 /* front, surround, clfe, side */
14071 0x03, 0x06, 0x05, 0x04
14072};
14073
9c7f852e
TI
14074static hda_nid_t alc660_dac_nids[3] = {
14075 /* front, clfe, surround */
14076 0x03, 0x05, 0x06
14077};
14078
df694daa
KY
14079static hda_nid_t alc861_adc_nids[1] = {
14080 /* ADC0-2 */
14081 0x08,
14082};
14083
14084static struct hda_input_mux alc861_capture_source = {
14085 .num_items = 5,
14086 .items = {
14087 { "Mic", 0x0 },
14088 { "Front Mic", 0x3 },
14089 { "Line", 0x1 },
14090 { "CD", 0x4 },
14091 { "Mixer", 0x5 },
14092 },
14093};
14094
1c20930a
TI
14095static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14096{
14097 struct alc_spec *spec = codec->spec;
14098 hda_nid_t mix, srcs[5];
14099 int i, j, num;
14100
14101 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14102 return 0;
14103 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14104 if (num < 0)
14105 return 0;
14106 for (i = 0; i < num; i++) {
14107 unsigned int type;
a22d543a 14108 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
14109 if (type != AC_WID_AUD_OUT)
14110 continue;
14111 for (j = 0; j < spec->multiout.num_dacs; j++)
14112 if (spec->multiout.dac_nids[j] == srcs[i])
14113 break;
14114 if (j >= spec->multiout.num_dacs)
14115 return srcs[i];
14116 }
14117 return 0;
14118}
14119
df694daa 14120/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 14121static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 14122 const struct auto_pin_cfg *cfg)
df694daa 14123{
1c20930a 14124 struct alc_spec *spec = codec->spec;
df694daa 14125 int i;
1c20930a 14126 hda_nid_t nid, dac;
df694daa
KY
14127
14128 spec->multiout.dac_nids = spec->private_dac_nids;
14129 for (i = 0; i < cfg->line_outs; i++) {
14130 nid = cfg->line_out_pins[i];
1c20930a
TI
14131 dac = alc861_look_for_dac(codec, nid);
14132 if (!dac)
14133 continue;
14134 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 14135 }
df694daa
KY
14136 return 0;
14137}
14138
1c20930a
TI
14139static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14140 hda_nid_t nid, unsigned int chs)
14141{
14142 char name[32];
14143 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
14144 return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
14145 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14146}
14147
df694daa 14148/* add playback controls from the parsed DAC table */
1c20930a 14149static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
14150 const struct auto_pin_cfg *cfg)
14151{
1c20930a 14152 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
14153 static const char *chname[4] = {
14154 "Front", "Surround", NULL /*CLFE*/, "Side"
14155 };
df694daa 14156 hda_nid_t nid;
1c20930a
TI
14157 int i, err;
14158
14159 if (cfg->line_outs == 1) {
14160 const char *pfx = NULL;
14161 if (!cfg->hp_outs)
14162 pfx = "Master";
14163 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14164 pfx = "Speaker";
14165 if (pfx) {
14166 nid = spec->multiout.dac_nids[0];
14167 return alc861_create_out_sw(codec, pfx, nid, 3);
14168 }
14169 }
df694daa
KY
14170
14171 for (i = 0; i < cfg->line_outs; i++) {
14172 nid = spec->multiout.dac_nids[i];
f12ab1e0 14173 if (!nid)
df694daa 14174 continue;
1c20930a 14175 if (i == 2) {
df694daa 14176 /* Center/LFE */
1c20930a 14177 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 14178 if (err < 0)
df694daa 14179 return err;
1c20930a 14180 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 14181 if (err < 0)
df694daa
KY
14182 return err;
14183 } else {
1c20930a 14184 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 14185 if (err < 0)
df694daa
KY
14186 return err;
14187 }
14188 }
14189 return 0;
14190}
14191
1c20930a 14192static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 14193{
1c20930a 14194 struct alc_spec *spec = codec->spec;
df694daa
KY
14195 int err;
14196 hda_nid_t nid;
14197
f12ab1e0 14198 if (!pin)
df694daa
KY
14199 return 0;
14200
14201 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
14202 nid = alc861_look_for_dac(codec, pin);
14203 if (nid) {
14204 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14205 if (err < 0)
14206 return err;
14207 spec->multiout.hp_nid = nid;
14208 }
df694daa
KY
14209 }
14210 return 0;
14211}
14212
14213/* create playback/capture controls for input pins */
05f5f477 14214static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 14215 const struct auto_pin_cfg *cfg)
df694daa 14216{
05f5f477 14217 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
14218}
14219
f12ab1e0
TI
14220static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14221 hda_nid_t nid,
1c20930a 14222 int pin_type, hda_nid_t dac)
df694daa 14223{
1c20930a
TI
14224 hda_nid_t mix, srcs[5];
14225 int i, num;
14226
564c5bea
JL
14227 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14228 pin_type);
1c20930a 14229 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 14230 AMP_OUT_UNMUTE);
1c20930a
TI
14231 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14232 return;
14233 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14234 if (num < 0)
14235 return;
14236 for (i = 0; i < num; i++) {
14237 unsigned int mute;
14238 if (srcs[i] == dac || srcs[i] == 0x15)
14239 mute = AMP_IN_UNMUTE(i);
14240 else
14241 mute = AMP_IN_MUTE(i);
14242 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14243 mute);
14244 }
df694daa
KY
14245}
14246
14247static void alc861_auto_init_multi_out(struct hda_codec *codec)
14248{
14249 struct alc_spec *spec = codec->spec;
14250 int i;
14251
14252 for (i = 0; i < spec->autocfg.line_outs; i++) {
14253 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14254 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 14255 if (nid)
baba8ee9 14256 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 14257 spec->multiout.dac_nids[i]);
df694daa
KY
14258 }
14259}
14260
14261static void alc861_auto_init_hp_out(struct hda_codec *codec)
14262{
14263 struct alc_spec *spec = codec->spec;
14264 hda_nid_t pin;
14265
eb06ed8f 14266 pin = spec->autocfg.hp_pins[0];
1c20930a 14267 if (pin)
f12ab1e0 14268 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
1c20930a 14269 spec->multiout.hp_nid);
f6c7e546
TI
14270 pin = spec->autocfg.speaker_pins[0];
14271 if (pin)
1c20930a
TI
14272 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT,
14273 spec->multiout.dac_nids[0]);
df694daa
KY
14274}
14275
14276static void alc861_auto_init_analog_input(struct hda_codec *codec)
14277{
14278 struct alc_spec *spec = codec->spec;
14279 int i;
14280
14281 for (i = 0; i < AUTO_PIN_LAST; i++) {
14282 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
14283 if (nid >= 0x0c && nid <= 0x11)
14284 alc_set_input_pin(codec, nid, i);
df694daa
KY
14285 }
14286}
14287
14288/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
14289/* return 1 if successful, 0 if the proper config is not found,
14290 * or a negative error code
14291 */
df694daa
KY
14292static int alc861_parse_auto_config(struct hda_codec *codec)
14293{
14294 struct alc_spec *spec = codec->spec;
14295 int err;
14296 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14297
f12ab1e0
TI
14298 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14299 alc861_ignore);
14300 if (err < 0)
df694daa 14301 return err;
f12ab1e0 14302 if (!spec->autocfg.line_outs)
df694daa
KY
14303 return 0; /* can't find valid BIOS pin config */
14304
1c20930a 14305 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
14306 if (err < 0)
14307 return err;
1c20930a 14308 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
14309 if (err < 0)
14310 return err;
1c20930a 14311 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
14312 if (err < 0)
14313 return err;
05f5f477 14314 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 14315 if (err < 0)
df694daa
KY
14316 return err;
14317
14318 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14319
0852d7a6 14320 if (spec->autocfg.dig_outs)
df694daa
KY
14321 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14322
603c4019 14323 if (spec->kctls.list)
d88897ea 14324 add_mixer(spec, spec->kctls.list);
df694daa 14325
d88897ea 14326 add_verb(spec, alc861_auto_init_verbs);
df694daa 14327
a1e8d2da 14328 spec->num_mux_defs = 1;
61b9b9b1 14329 spec->input_mux = &spec->private_imux[0];
df694daa
KY
14330
14331 spec->adc_nids = alc861_adc_nids;
14332 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 14333 set_capture_mixer(codec);
df694daa 14334
4a79ba34
TI
14335 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14336
df694daa
KY
14337 return 1;
14338}
14339
ae6b813a
TI
14340/* additional initialization for auto-configuration model */
14341static void alc861_auto_init(struct hda_codec *codec)
df694daa 14342{
f6c7e546 14343 struct alc_spec *spec = codec->spec;
df694daa
KY
14344 alc861_auto_init_multi_out(codec);
14345 alc861_auto_init_hp_out(codec);
14346 alc861_auto_init_analog_input(codec);
f6c7e546 14347 if (spec->unsol_event)
7fb0d78f 14348 alc_inithook(codec);
df694daa
KY
14349}
14350
cb53c626
TI
14351#ifdef CONFIG_SND_HDA_POWER_SAVE
14352static struct hda_amp_list alc861_loopbacks[] = {
14353 { 0x15, HDA_INPUT, 0 },
14354 { 0x15, HDA_INPUT, 1 },
14355 { 0x15, HDA_INPUT, 2 },
14356 { 0x15, HDA_INPUT, 3 },
14357 { } /* end */
14358};
14359#endif
14360
df694daa
KY
14361
14362/*
14363 * configuration and preset
14364 */
f5fcc13c
TI
14365static const char *alc861_models[ALC861_MODEL_LAST] = {
14366 [ALC861_3ST] = "3stack",
14367 [ALC660_3ST] = "3stack-660",
14368 [ALC861_3ST_DIG] = "3stack-dig",
14369 [ALC861_6ST_DIG] = "6stack-dig",
14370 [ALC861_UNIWILL_M31] = "uniwill-m31",
14371 [ALC861_TOSHIBA] = "toshiba",
14372 [ALC861_ASUS] = "asus",
14373 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14374 [ALC861_AUTO] = "auto",
14375};
14376
14377static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 14378 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
14379 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14380 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14381 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 14382 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 14383 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 14384 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
14385 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14386 * Any other models that need this preset?
14387 */
14388 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
14389 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14390 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 14391 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
14392 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14393 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14394 /* FIXME: the below seems conflict */
14395 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 14396 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 14397 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
14398 {}
14399};
14400
14401static struct alc_config_preset alc861_presets[] = {
14402 [ALC861_3ST] = {
14403 .mixers = { alc861_3ST_mixer },
14404 .init_verbs = { alc861_threestack_init_verbs },
14405 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14406 .dac_nids = alc861_dac_nids,
14407 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14408 .channel_mode = alc861_threestack_modes,
4e195a7b 14409 .need_dac_fix = 1,
df694daa
KY
14410 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14411 .adc_nids = alc861_adc_nids,
14412 .input_mux = &alc861_capture_source,
14413 },
14414 [ALC861_3ST_DIG] = {
14415 .mixers = { alc861_base_mixer },
14416 .init_verbs = { alc861_threestack_init_verbs },
14417 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14418 .dac_nids = alc861_dac_nids,
14419 .dig_out_nid = ALC861_DIGOUT_NID,
14420 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14421 .channel_mode = alc861_threestack_modes,
4e195a7b 14422 .need_dac_fix = 1,
df694daa
KY
14423 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14424 .adc_nids = alc861_adc_nids,
14425 .input_mux = &alc861_capture_source,
14426 },
14427 [ALC861_6ST_DIG] = {
14428 .mixers = { alc861_base_mixer },
14429 .init_verbs = { alc861_base_init_verbs },
14430 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14431 .dac_nids = alc861_dac_nids,
14432 .dig_out_nid = ALC861_DIGOUT_NID,
14433 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14434 .channel_mode = alc861_8ch_modes,
14435 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14436 .adc_nids = alc861_adc_nids,
14437 .input_mux = &alc861_capture_source,
14438 },
9c7f852e
TI
14439 [ALC660_3ST] = {
14440 .mixers = { alc861_3ST_mixer },
14441 .init_verbs = { alc861_threestack_init_verbs },
14442 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14443 .dac_nids = alc660_dac_nids,
14444 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14445 .channel_mode = alc861_threestack_modes,
4e195a7b 14446 .need_dac_fix = 1,
9c7f852e
TI
14447 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14448 .adc_nids = alc861_adc_nids,
14449 .input_mux = &alc861_capture_source,
14450 },
22309c3e
TI
14451 [ALC861_UNIWILL_M31] = {
14452 .mixers = { alc861_uniwill_m31_mixer },
14453 .init_verbs = { alc861_uniwill_m31_init_verbs },
14454 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14455 .dac_nids = alc861_dac_nids,
14456 .dig_out_nid = ALC861_DIGOUT_NID,
14457 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14458 .channel_mode = alc861_uniwill_m31_modes,
14459 .need_dac_fix = 1,
14460 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14461 .adc_nids = alc861_adc_nids,
14462 .input_mux = &alc861_capture_source,
14463 },
a53d1aec
TD
14464 [ALC861_TOSHIBA] = {
14465 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
14466 .init_verbs = { alc861_base_init_verbs,
14467 alc861_toshiba_init_verbs },
a53d1aec
TD
14468 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14469 .dac_nids = alc861_dac_nids,
14470 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14471 .channel_mode = alc883_3ST_2ch_modes,
14472 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14473 .adc_nids = alc861_adc_nids,
14474 .input_mux = &alc861_capture_source,
14475 .unsol_event = alc861_toshiba_unsol_event,
14476 .init_hook = alc861_toshiba_automute,
14477 },
7cdbff94
MD
14478 [ALC861_ASUS] = {
14479 .mixers = { alc861_asus_mixer },
14480 .init_verbs = { alc861_asus_init_verbs },
14481 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14482 .dac_nids = alc861_dac_nids,
14483 .dig_out_nid = ALC861_DIGOUT_NID,
14484 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14485 .channel_mode = alc861_asus_modes,
14486 .need_dac_fix = 1,
14487 .hp_nid = 0x06,
14488 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14489 .adc_nids = alc861_adc_nids,
14490 .input_mux = &alc861_capture_source,
14491 },
56bb0cab
TI
14492 [ALC861_ASUS_LAPTOP] = {
14493 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14494 .init_verbs = { alc861_asus_init_verbs,
14495 alc861_asus_laptop_init_verbs },
14496 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14497 .dac_nids = alc861_dac_nids,
14498 .dig_out_nid = ALC861_DIGOUT_NID,
14499 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14500 .channel_mode = alc883_3ST_2ch_modes,
14501 .need_dac_fix = 1,
14502 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14503 .adc_nids = alc861_adc_nids,
14504 .input_mux = &alc861_capture_source,
14505 },
14506};
df694daa
KY
14507
14508
14509static int patch_alc861(struct hda_codec *codec)
14510{
14511 struct alc_spec *spec;
14512 int board_config;
14513 int err;
14514
dc041e0b 14515 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
14516 if (spec == NULL)
14517 return -ENOMEM;
14518
f12ab1e0 14519 codec->spec = spec;
df694daa 14520
f5fcc13c
TI
14521 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14522 alc861_models,
14523 alc861_cfg_tbl);
9c7f852e 14524
f5fcc13c 14525 if (board_config < 0) {
9a11f1aa
TI
14526 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14527 codec->chip_name);
df694daa
KY
14528 board_config = ALC861_AUTO;
14529 }
14530
14531 if (board_config == ALC861_AUTO) {
14532 /* automatic parse from the BIOS config */
14533 err = alc861_parse_auto_config(codec);
14534 if (err < 0) {
14535 alc_free(codec);
14536 return err;
f12ab1e0 14537 } else if (!err) {
9c7f852e
TI
14538 printk(KERN_INFO
14539 "hda_codec: Cannot set up configuration "
14540 "from BIOS. Using base mode...\n");
df694daa
KY
14541 board_config = ALC861_3ST_DIG;
14542 }
14543 }
14544
680cd536
KK
14545 err = snd_hda_attach_beep_device(codec, 0x23);
14546 if (err < 0) {
14547 alc_free(codec);
14548 return err;
14549 }
14550
df694daa 14551 if (board_config != ALC861_AUTO)
e9c364c0 14552 setup_preset(codec, &alc861_presets[board_config]);
df694daa 14553
df694daa
KY
14554 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14555 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14556
df694daa
KY
14557 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14558 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14559
45bdd1c1
TI
14560 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14561
2134ea4f
TI
14562 spec->vmaster_nid = 0x03;
14563
df694daa
KY
14564 codec->patch_ops = alc_patch_ops;
14565 if (board_config == ALC861_AUTO)
ae6b813a 14566 spec->init_hook = alc861_auto_init;
cb53c626
TI
14567#ifdef CONFIG_SND_HDA_POWER_SAVE
14568 if (!spec->loopback.amplist)
14569 spec->loopback.amplist = alc861_loopbacks;
14570#endif
daead538 14571 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 14572
1da177e4
LT
14573 return 0;
14574}
14575
f32610ed
JS
14576/*
14577 * ALC861-VD support
14578 *
14579 * Based on ALC882
14580 *
14581 * In addition, an independent DAC
14582 */
14583#define ALC861VD_DIGOUT_NID 0x06
14584
14585static hda_nid_t alc861vd_dac_nids[4] = {
14586 /* front, surr, clfe, side surr */
14587 0x02, 0x03, 0x04, 0x05
14588};
14589
14590/* dac_nids for ALC660vd are in a different order - according to
14591 * Realtek's driver.
def319f9 14592 * This should probably result in a different mixer for 6stack models
f32610ed
JS
14593 * of ALC660vd codecs, but for now there is only 3stack mixer
14594 * - and it is the same as in 861vd.
14595 * adc_nids in ALC660vd are (is) the same as in 861vd
14596 */
14597static hda_nid_t alc660vd_dac_nids[3] = {
14598 /* front, rear, clfe, rear_surr */
14599 0x02, 0x04, 0x03
14600};
14601
14602static hda_nid_t alc861vd_adc_nids[1] = {
14603 /* ADC0 */
14604 0x09,
14605};
14606
e1406348
TI
14607static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14608
f32610ed
JS
14609/* input MUX */
14610/* FIXME: should be a matrix-type input source selection */
14611static struct hda_input_mux alc861vd_capture_source = {
14612 .num_items = 4,
14613 .items = {
14614 { "Mic", 0x0 },
14615 { "Front Mic", 0x1 },
14616 { "Line", 0x2 },
14617 { "CD", 0x4 },
14618 },
14619};
14620
272a527c 14621static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 14622 .num_items = 2,
272a527c 14623 .items = {
b419f346
TD
14624 { "Ext Mic", 0x0 },
14625 { "Int Mic", 0x1 },
272a527c
KY
14626 },
14627};
14628
d1a991a6
KY
14629static struct hda_input_mux alc861vd_hp_capture_source = {
14630 .num_items = 2,
14631 .items = {
14632 { "Front Mic", 0x0 },
14633 { "ATAPI Mic", 0x1 },
14634 },
14635};
14636
f32610ed
JS
14637/*
14638 * 2ch mode
14639 */
14640static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14641 { 2, NULL }
14642};
14643
14644/*
14645 * 6ch mode
14646 */
14647static struct hda_verb alc861vd_6stack_ch6_init[] = {
14648 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14649 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14650 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14651 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14652 { } /* end */
14653};
14654
14655/*
14656 * 8ch mode
14657 */
14658static struct hda_verb alc861vd_6stack_ch8_init[] = {
14659 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14660 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14661 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14662 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14663 { } /* end */
14664};
14665
14666static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14667 { 6, alc861vd_6stack_ch6_init },
14668 { 8, alc861vd_6stack_ch8_init },
14669};
14670
14671static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14672 {
14673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14674 .name = "Channel Mode",
14675 .info = alc_ch_mode_info,
14676 .get = alc_ch_mode_get,
14677 .put = alc_ch_mode_put,
14678 },
14679 { } /* end */
14680};
14681
f32610ed
JS
14682/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14683 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14684 */
14685static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14686 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14687 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14688
14689 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14690 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14691
14692 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14693 HDA_OUTPUT),
14694 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14695 HDA_OUTPUT),
14696 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14697 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14698
14699 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14700 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14701
14702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14703
14704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14707
14708 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14709 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14710 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14711
14712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14714
14715 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14716 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14717
f32610ed
JS
14718 { } /* end */
14719};
14720
14721static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14722 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14723 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14724
14725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14726
14727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14730
14731 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14732 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14733 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14734
14735 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14736 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14737
14738 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14739 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14740
f32610ed
JS
14741 { } /* end */
14742};
14743
bdd148a3
KY
14744static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14745 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14746 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14747 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14748
14749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14750
14751 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14753 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14754
14755 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14756 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14757 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14758
14759 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14760 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14761
14762 { } /* end */
14763};
14764
b419f346
TD
14765/* Pin assignment: Speaker=0x14, HP = 0x15,
14766 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
14767 */
14768static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
14769 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14770 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
14771 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14772 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
14773 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14774 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14775 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14776 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14777 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14778 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
14779 { } /* end */
14780};
14781
d1a991a6
KY
14782/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14783 * Front Mic=0x18, ATAPI Mic = 0x19,
14784 */
14785static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14786 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14787 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14788 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14789 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14790 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14791 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14792 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14793 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 14794
d1a991a6
KY
14795 { } /* end */
14796};
14797
f32610ed
JS
14798/*
14799 * generic initialization of ADC, input mixers and output mixers
14800 */
14801static struct hda_verb alc861vd_volume_init_verbs[] = {
14802 /*
14803 * Unmute ADC0 and set the default input to mic-in
14804 */
14805 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14807
14808 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14809 * the analog-loopback mixer widget
14810 */
14811 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14812 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14816 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
14817
14818 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
14819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14821 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 14822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
14823
14824 /*
14825 * Set up output mixers (0x02 - 0x05)
14826 */
14827 /* set vol=0 to output mixers */
14828 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14829 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14830 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14831 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14832
14833 /* set up input amps for analog loopback */
14834 /* Amp Indices: DAC = 0, mixer = 1 */
14835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14843
14844 { }
14845};
14846
14847/*
14848 * 3-stack pin configuration:
14849 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14850 */
14851static struct hda_verb alc861vd_3stack_init_verbs[] = {
14852 /*
14853 * Set pin mode and muting
14854 */
14855 /* set front pin widgets 0x14 for output */
14856 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14857 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14858 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14859
14860 /* Mic (rear) pin: input vref at 80% */
14861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14862 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14863 /* Front Mic pin: input vref at 80% */
14864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14866 /* Line In pin: input */
14867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14869 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14871 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14872 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14873 /* CD pin widget for input */
14874 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14875
14876 { }
14877};
14878
14879/*
14880 * 6-stack pin configuration:
14881 */
14882static struct hda_verb alc861vd_6stack_init_verbs[] = {
14883 /*
14884 * Set pin mode and muting
14885 */
14886 /* set front pin widgets 0x14 for output */
14887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14890
14891 /* Rear Pin: output 1 (0x0d) */
14892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14893 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14894 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14895 /* CLFE Pin: output 2 (0x0e) */
14896 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14897 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14898 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14899 /* Side Pin: output 3 (0x0f) */
14900 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14901 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14902 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14903
14904 /* Mic (rear) pin: input vref at 80% */
14905 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14907 /* Front Mic pin: input vref at 80% */
14908 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14909 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14910 /* Line In pin: input */
14911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14912 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14913 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14914 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14915 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14916 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14917 /* CD pin widget for input */
14918 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14919
14920 { }
14921};
14922
bdd148a3
KY
14923static struct hda_verb alc861vd_eapd_verbs[] = {
14924 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14925 { }
14926};
14927
f9423e7a
KY
14928static struct hda_verb alc660vd_eapd_verbs[] = {
14929 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14930 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14931 { }
14932};
14933
bdd148a3
KY
14934static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14937 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14939 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14940 {}
14941};
14942
bdd148a3
KY
14943static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14944{
14945 unsigned int present;
14946 unsigned char bits;
14947
14948 present = snd_hda_codec_read(codec, 0x18, 0,
14949 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14950 bits = present ? HDA_AMP_MUTE : 0;
14951 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14952 HDA_AMP_MUTE, bits);
bdd148a3
KY
14953}
14954
4f5d1706 14955static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 14956{
a9fd4f3f 14957 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
14958 spec->autocfg.hp_pins[0] = 0x1b;
14959 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14960}
14961
14962static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14963{
a9fd4f3f 14964 alc_automute_amp(codec);
bdd148a3
KY
14965 alc861vd_lenovo_mic_automute(codec);
14966}
14967
14968static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14969 unsigned int res)
14970{
14971 switch (res >> 26) {
bdd148a3
KY
14972 case ALC880_MIC_EVENT:
14973 alc861vd_lenovo_mic_automute(codec);
14974 break;
a9fd4f3f
TI
14975 default:
14976 alc_automute_amp_unsol_event(codec, res);
14977 break;
bdd148a3
KY
14978 }
14979}
14980
272a527c
KY
14981static struct hda_verb alc861vd_dallas_verbs[] = {
14982 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14983 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14984 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14985 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14986
14987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14989 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14991 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14992 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14993 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14995
272a527c
KY
14996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14997 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14998 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15000 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15001 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15002 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15003 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15004
15005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15007 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15008 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15009 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15010 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15012 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15013
15014 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15015 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15017 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15018
15019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 15020 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
15021 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15022
15023 { } /* end */
15024};
15025
15026/* toggle speaker-output according to the hp-jack state */
4f5d1706 15027static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 15028{
a9fd4f3f 15029 struct alc_spec *spec = codec->spec;
272a527c 15030
a9fd4f3f
TI
15031 spec->autocfg.hp_pins[0] = 0x15;
15032 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
15033}
15034
cb53c626
TI
15035#ifdef CONFIG_SND_HDA_POWER_SAVE
15036#define alc861vd_loopbacks alc880_loopbacks
15037#endif
15038
def319f9 15039/* pcm configuration: identical with ALC880 */
f32610ed
JS
15040#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15041#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15042#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15043#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15044
15045/*
15046 * configuration and preset
15047 */
15048static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15049 [ALC660VD_3ST] = "3stack-660",
983f8ae4 15050 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 15051 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
15052 [ALC861VD_3ST] = "3stack",
15053 [ALC861VD_3ST_DIG] = "3stack-digout",
15054 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 15055 [ALC861VD_LENOVO] = "lenovo",
272a527c 15056 [ALC861VD_DALLAS] = "dallas",
983f8ae4 15057 [ALC861VD_HP] = "hp",
f32610ed
JS
15058 [ALC861VD_AUTO] = "auto",
15059};
15060
15061static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
15062 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15063 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 15064 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 15065 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13c94744 15066 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 15067 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 15068 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 15069 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 15070 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 15071 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 15072 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 15073 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 15074 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 15075 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 15076 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
15077 {}
15078};
15079
15080static struct alc_config_preset alc861vd_presets[] = {
15081 [ALC660VD_3ST] = {
15082 .mixers = { alc861vd_3st_mixer },
15083 .init_verbs = { alc861vd_volume_init_verbs,
15084 alc861vd_3stack_init_verbs },
15085 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15086 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
15087 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15088 .channel_mode = alc861vd_3stack_2ch_modes,
15089 .input_mux = &alc861vd_capture_source,
15090 },
6963f84c
MC
15091 [ALC660VD_3ST_DIG] = {
15092 .mixers = { alc861vd_3st_mixer },
15093 .init_verbs = { alc861vd_volume_init_verbs,
15094 alc861vd_3stack_init_verbs },
15095 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15096 .dac_nids = alc660vd_dac_nids,
15097 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
15098 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15099 .channel_mode = alc861vd_3stack_2ch_modes,
15100 .input_mux = &alc861vd_capture_source,
15101 },
f32610ed
JS
15102 [ALC861VD_3ST] = {
15103 .mixers = { alc861vd_3st_mixer },
15104 .init_verbs = { alc861vd_volume_init_verbs,
15105 alc861vd_3stack_init_verbs },
15106 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15107 .dac_nids = alc861vd_dac_nids,
15108 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15109 .channel_mode = alc861vd_3stack_2ch_modes,
15110 .input_mux = &alc861vd_capture_source,
15111 },
15112 [ALC861VD_3ST_DIG] = {
15113 .mixers = { alc861vd_3st_mixer },
15114 .init_verbs = { alc861vd_volume_init_verbs,
15115 alc861vd_3stack_init_verbs },
15116 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15117 .dac_nids = alc861vd_dac_nids,
15118 .dig_out_nid = ALC861VD_DIGOUT_NID,
15119 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15120 .channel_mode = alc861vd_3stack_2ch_modes,
15121 .input_mux = &alc861vd_capture_source,
15122 },
15123 [ALC861VD_6ST_DIG] = {
15124 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15125 .init_verbs = { alc861vd_volume_init_verbs,
15126 alc861vd_6stack_init_verbs },
15127 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15128 .dac_nids = alc861vd_dac_nids,
15129 .dig_out_nid = ALC861VD_DIGOUT_NID,
15130 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15131 .channel_mode = alc861vd_6stack_modes,
15132 .input_mux = &alc861vd_capture_source,
15133 },
bdd148a3
KY
15134 [ALC861VD_LENOVO] = {
15135 .mixers = { alc861vd_lenovo_mixer },
15136 .init_verbs = { alc861vd_volume_init_verbs,
15137 alc861vd_3stack_init_verbs,
15138 alc861vd_eapd_verbs,
15139 alc861vd_lenovo_unsol_verbs },
15140 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15141 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
15142 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15143 .channel_mode = alc861vd_3stack_2ch_modes,
15144 .input_mux = &alc861vd_capture_source,
15145 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 15146 .setup = alc861vd_lenovo_setup,
a9fd4f3f 15147 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 15148 },
272a527c
KY
15149 [ALC861VD_DALLAS] = {
15150 .mixers = { alc861vd_dallas_mixer },
15151 .init_verbs = { alc861vd_dallas_verbs },
15152 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15153 .dac_nids = alc861vd_dac_nids,
272a527c
KY
15154 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15155 .channel_mode = alc861vd_3stack_2ch_modes,
15156 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 15157 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
15158 .setup = alc861vd_dallas_setup,
15159 .init_hook = alc_automute_amp,
d1a991a6
KY
15160 },
15161 [ALC861VD_HP] = {
15162 .mixers = { alc861vd_hp_mixer },
15163 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15164 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15165 .dac_nids = alc861vd_dac_nids,
d1a991a6 15166 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
15167 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15168 .channel_mode = alc861vd_3stack_2ch_modes,
15169 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 15170 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
15171 .setup = alc861vd_dallas_setup,
15172 .init_hook = alc_automute_amp,
ea1fb29a 15173 },
13c94744
TI
15174 [ALC660VD_ASUS_V1S] = {
15175 .mixers = { alc861vd_lenovo_mixer },
15176 .init_verbs = { alc861vd_volume_init_verbs,
15177 alc861vd_3stack_init_verbs,
15178 alc861vd_eapd_verbs,
15179 alc861vd_lenovo_unsol_verbs },
15180 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15181 .dac_nids = alc660vd_dac_nids,
15182 .dig_out_nid = ALC861VD_DIGOUT_NID,
15183 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15184 .channel_mode = alc861vd_3stack_2ch_modes,
15185 .input_mux = &alc861vd_capture_source,
15186 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 15187 .setup = alc861vd_lenovo_setup,
a9fd4f3f 15188 .init_hook = alc861vd_lenovo_init_hook,
13c94744 15189 },
f32610ed
JS
15190};
15191
15192/*
15193 * BIOS auto configuration
15194 */
05f5f477
TI
15195static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15196 const struct auto_pin_cfg *cfg)
15197{
15198 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15199}
15200
15201
f32610ed
JS
15202static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15203 hda_nid_t nid, int pin_type, int dac_idx)
15204{
f6c7e546 15205 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
15206}
15207
15208static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15209{
15210 struct alc_spec *spec = codec->spec;
15211 int i;
15212
15213 for (i = 0; i <= HDA_SIDE; i++) {
15214 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15215 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
15216 if (nid)
15217 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 15218 pin_type, i);
f32610ed
JS
15219 }
15220}
15221
15222
15223static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15224{
15225 struct alc_spec *spec = codec->spec;
15226 hda_nid_t pin;
15227
15228 pin = spec->autocfg.hp_pins[0];
def319f9 15229 if (pin) /* connect to front and use dac 0 */
f32610ed 15230 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
15231 pin = spec->autocfg.speaker_pins[0];
15232 if (pin)
15233 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
15234}
15235
f32610ed
JS
15236#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15237
15238static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15239{
15240 struct alc_spec *spec = codec->spec;
15241 int i;
15242
15243 for (i = 0; i < AUTO_PIN_LAST; i++) {
15244 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 15245 if (alc_is_input_pin(codec, nid)) {
23f0c048 15246 alc_set_input_pin(codec, nid, i);
e82c025b
TI
15247 if (nid != ALC861VD_PIN_CD_NID &&
15248 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
15249 snd_hda_codec_write(codec, nid, 0,
15250 AC_VERB_SET_AMP_GAIN_MUTE,
15251 AMP_OUT_MUTE);
15252 }
15253 }
15254}
15255
f511b01c
TI
15256#define alc861vd_auto_init_input_src alc882_auto_init_input_src
15257
f32610ed
JS
15258#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15259#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15260
15261/* add playback controls from the parsed DAC table */
15262/* Based on ALC880 version. But ALC861VD has separate,
15263 * different NIDs for mute/unmute switch and volume control */
15264static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15265 const struct auto_pin_cfg *cfg)
15266{
15267 char name[32];
15268 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15269 hda_nid_t nid_v, nid_s;
15270 int i, err;
15271
15272 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 15273 if (!spec->multiout.dac_nids[i])
f32610ed
JS
15274 continue;
15275 nid_v = alc861vd_idx_to_mixer_vol(
15276 alc880_dac_to_idx(
15277 spec->multiout.dac_nids[i]));
15278 nid_s = alc861vd_idx_to_mixer_switch(
15279 alc880_dac_to_idx(
15280 spec->multiout.dac_nids[i]));
15281
15282 if (i == 2) {
15283 /* Center/LFE */
f12ab1e0
TI
15284 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15285 "Center Playback Volume",
15286 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15287 HDA_OUTPUT));
15288 if (err < 0)
f32610ed 15289 return err;
f12ab1e0
TI
15290 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15291 "LFE Playback Volume",
15292 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15293 HDA_OUTPUT));
15294 if (err < 0)
f32610ed 15295 return err;
f12ab1e0
TI
15296 err = add_control(spec, ALC_CTL_BIND_MUTE,
15297 "Center Playback Switch",
15298 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15299 HDA_INPUT));
15300 if (err < 0)
f32610ed 15301 return err;
f12ab1e0
TI
15302 err = add_control(spec, ALC_CTL_BIND_MUTE,
15303 "LFE Playback Switch",
15304 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15305 HDA_INPUT));
15306 if (err < 0)
f32610ed
JS
15307 return err;
15308 } else {
a4fcd491
TI
15309 const char *pfx;
15310 if (cfg->line_outs == 1 &&
15311 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15312 if (!cfg->hp_pins)
15313 pfx = "Speaker";
15314 else
15315 pfx = "PCM";
15316 } else
15317 pfx = chname[i];
15318 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
15319 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15320 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15321 HDA_OUTPUT));
15322 if (err < 0)
f32610ed 15323 return err;
a4fcd491
TI
15324 if (cfg->line_outs == 1 &&
15325 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15326 pfx = "Speaker";
15327 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0 15328 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 15329 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
15330 HDA_INPUT));
15331 if (err < 0)
f32610ed
JS
15332 return err;
15333 }
15334 }
15335 return 0;
15336}
15337
15338/* add playback controls for speaker and HP outputs */
15339/* Based on ALC880 version. But ALC861VD has separate,
15340 * different NIDs for mute/unmute switch and volume control */
15341static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15342 hda_nid_t pin, const char *pfx)
15343{
15344 hda_nid_t nid_v, nid_s;
15345 int err;
15346 char name[32];
15347
f12ab1e0 15348 if (!pin)
f32610ed
JS
15349 return 0;
15350
15351 if (alc880_is_fixed_pin(pin)) {
15352 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15353 /* specify the DAC as the extra output */
f12ab1e0 15354 if (!spec->multiout.hp_nid)
f32610ed
JS
15355 spec->multiout.hp_nid = nid_v;
15356 else
15357 spec->multiout.extra_out_nid[0] = nid_v;
15358 /* control HP volume/switch on the output mixer amp */
15359 nid_v = alc861vd_idx_to_mixer_vol(
15360 alc880_fixed_pin_idx(pin));
15361 nid_s = alc861vd_idx_to_mixer_switch(
15362 alc880_fixed_pin_idx(pin));
15363
15364 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
15365 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15366 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15367 if (err < 0)
f32610ed
JS
15368 return err;
15369 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
15370 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15371 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15372 if (err < 0)
f32610ed
JS
15373 return err;
15374 } else if (alc880_is_multi_pin(pin)) {
15375 /* set manual connection */
15376 /* we have only a switch on HP-out PIN */
15377 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
15378 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15379 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15380 if (err < 0)
f32610ed
JS
15381 return err;
15382 }
15383 return 0;
15384}
15385
15386/* parse the BIOS configuration and set up the alc_spec
15387 * return 1 if successful, 0 if the proper config is not found,
15388 * or a negative error code
15389 * Based on ALC880 version - had to change it to override
15390 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15391static int alc861vd_parse_auto_config(struct hda_codec *codec)
15392{
15393 struct alc_spec *spec = codec->spec;
15394 int err;
15395 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15396
f12ab1e0
TI
15397 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15398 alc861vd_ignore);
15399 if (err < 0)
f32610ed 15400 return err;
f12ab1e0 15401 if (!spec->autocfg.line_outs)
f32610ed
JS
15402 return 0; /* can't find valid BIOS pin config */
15403
f12ab1e0
TI
15404 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15405 if (err < 0)
15406 return err;
15407 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15408 if (err < 0)
15409 return err;
15410 err = alc861vd_auto_create_extra_out(spec,
15411 spec->autocfg.speaker_pins[0],
15412 "Speaker");
15413 if (err < 0)
15414 return err;
15415 err = alc861vd_auto_create_extra_out(spec,
15416 spec->autocfg.hp_pins[0],
15417 "Headphone");
15418 if (err < 0)
15419 return err;
05f5f477 15420 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15421 if (err < 0)
f32610ed
JS
15422 return err;
15423
15424 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15425
0852d7a6 15426 if (spec->autocfg.dig_outs)
f32610ed
JS
15427 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15428
603c4019 15429 if (spec->kctls.list)
d88897ea 15430 add_mixer(spec, spec->kctls.list);
f32610ed 15431
d88897ea 15432 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
15433
15434 spec->num_mux_defs = 1;
61b9b9b1 15435 spec->input_mux = &spec->private_imux[0];
f32610ed 15436
776e184e
TI
15437 err = alc_auto_add_mic_boost(codec);
15438 if (err < 0)
15439 return err;
15440
4a79ba34
TI
15441 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15442
f32610ed
JS
15443 return 1;
15444}
15445
15446/* additional initialization for auto-configuration model */
15447static void alc861vd_auto_init(struct hda_codec *codec)
15448{
f6c7e546 15449 struct alc_spec *spec = codec->spec;
f32610ed
JS
15450 alc861vd_auto_init_multi_out(codec);
15451 alc861vd_auto_init_hp_out(codec);
15452 alc861vd_auto_init_analog_input(codec);
f511b01c 15453 alc861vd_auto_init_input_src(codec);
f6c7e546 15454 if (spec->unsol_event)
7fb0d78f 15455 alc_inithook(codec);
f32610ed
JS
15456}
15457
15458static int patch_alc861vd(struct hda_codec *codec)
15459{
15460 struct alc_spec *spec;
15461 int err, board_config;
15462
15463 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15464 if (spec == NULL)
15465 return -ENOMEM;
15466
15467 codec->spec = spec;
15468
15469 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15470 alc861vd_models,
15471 alc861vd_cfg_tbl);
15472
15473 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
15474 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15475 codec->chip_name);
f32610ed
JS
15476 board_config = ALC861VD_AUTO;
15477 }
15478
15479 if (board_config == ALC861VD_AUTO) {
15480 /* automatic parse from the BIOS config */
15481 err = alc861vd_parse_auto_config(codec);
15482 if (err < 0) {
15483 alc_free(codec);
15484 return err;
f12ab1e0 15485 } else if (!err) {
f32610ed
JS
15486 printk(KERN_INFO
15487 "hda_codec: Cannot set up configuration "
15488 "from BIOS. Using base mode...\n");
15489 board_config = ALC861VD_3ST;
15490 }
15491 }
15492
680cd536
KK
15493 err = snd_hda_attach_beep_device(codec, 0x23);
15494 if (err < 0) {
15495 alc_free(codec);
15496 return err;
15497 }
15498
f32610ed 15499 if (board_config != ALC861VD_AUTO)
e9c364c0 15500 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 15501
2f893286 15502 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 15503 /* always turn on EAPD */
d88897ea 15504 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
15505 }
15506
f32610ed
JS
15507 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15508 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15509
f32610ed
JS
15510 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15511 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15512
dd704698
TI
15513 if (!spec->adc_nids) {
15514 spec->adc_nids = alc861vd_adc_nids;
15515 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15516 }
15517 if (!spec->capsrc_nids)
15518 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 15519
b59bdf3b 15520 set_capture_mixer(codec);
45bdd1c1 15521 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 15522
2134ea4f
TI
15523 spec->vmaster_nid = 0x02;
15524
f32610ed
JS
15525 codec->patch_ops = alc_patch_ops;
15526
15527 if (board_config == ALC861VD_AUTO)
15528 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
15529#ifdef CONFIG_SND_HDA_POWER_SAVE
15530 if (!spec->loopback.amplist)
15531 spec->loopback.amplist = alc861vd_loopbacks;
15532#endif
daead538 15533 codec->proc_widget_hook = print_realtek_coef;
f32610ed
JS
15534
15535 return 0;
15536}
15537
bc9f98a9
KY
15538/*
15539 * ALC662 support
15540 *
15541 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15542 * configuration. Each pin widget can choose any input DACs and a mixer.
15543 * Each ADC is connected from a mixer of all inputs. This makes possible
15544 * 6-channel independent captures.
15545 *
15546 * In addition, an independent DAC for the multi-playback (not used in this
15547 * driver yet).
15548 */
15549#define ALC662_DIGOUT_NID 0x06
15550#define ALC662_DIGIN_NID 0x0a
15551
15552static hda_nid_t alc662_dac_nids[4] = {
15553 /* front, rear, clfe, rear_surr */
15554 0x02, 0x03, 0x04
15555};
15556
622e84cd
KY
15557static hda_nid_t alc272_dac_nids[2] = {
15558 0x02, 0x03
15559};
15560
b59bdf3b 15561static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 15562 /* ADC1-2 */
b59bdf3b 15563 0x09, 0x08
bc9f98a9 15564};
e1406348 15565
622e84cd
KY
15566static hda_nid_t alc272_adc_nids[1] = {
15567 /* ADC1-2 */
15568 0x08,
15569};
15570
b59bdf3b 15571static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
15572static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15573
e1406348 15574
bc9f98a9
KY
15575/* input MUX */
15576/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
15577static struct hda_input_mux alc662_capture_source = {
15578 .num_items = 4,
15579 .items = {
15580 { "Mic", 0x0 },
15581 { "Front Mic", 0x1 },
15582 { "Line", 0x2 },
15583 { "CD", 0x4 },
15584 },
15585};
15586
15587static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15588 .num_items = 2,
15589 .items = {
15590 { "Mic", 0x1 },
15591 { "Line", 0x2 },
15592 },
15593};
291702f0 15594
6dda9f4a
KY
15595static struct hda_input_mux alc663_capture_source = {
15596 .num_items = 3,
15597 .items = {
15598 { "Mic", 0x0 },
15599 { "Front Mic", 0x1 },
15600 { "Line", 0x2 },
15601 },
15602};
15603
4f5d1706 15604#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
15605static struct hda_input_mux alc272_nc10_capture_source = {
15606 .num_items = 16,
15607 .items = {
15608 { "Autoselect Mic", 0x0 },
15609 { "Internal Mic", 0x1 },
15610 { "In-0x02", 0x2 },
15611 { "In-0x03", 0x3 },
15612 { "In-0x04", 0x4 },
15613 { "In-0x05", 0x5 },
15614 { "In-0x06", 0x6 },
15615 { "In-0x07", 0x7 },
15616 { "In-0x08", 0x8 },
15617 { "In-0x09", 0x9 },
15618 { "In-0x0a", 0x0a },
15619 { "In-0x0b", 0x0b },
15620 { "In-0x0c", 0x0c },
15621 { "In-0x0d", 0x0d },
15622 { "In-0x0e", 0x0e },
15623 { "In-0x0f", 0x0f },
15624 },
15625};
15626#endif
15627
bc9f98a9
KY
15628/*
15629 * 2ch mode
15630 */
15631static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15632 { 2, NULL }
15633};
15634
15635/*
15636 * 2ch mode
15637 */
15638static struct hda_verb alc662_3ST_ch2_init[] = {
15639 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15640 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15643 { } /* end */
15644};
15645
15646/*
15647 * 6ch mode
15648 */
15649static struct hda_verb alc662_3ST_ch6_init[] = {
15650 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15651 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15652 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15653 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15654 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15655 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15656 { } /* end */
15657};
15658
15659static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15660 { 2, alc662_3ST_ch2_init },
15661 { 6, alc662_3ST_ch6_init },
15662};
15663
15664/*
15665 * 2ch mode
15666 */
15667static struct hda_verb alc662_sixstack_ch6_init[] = {
15668 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15669 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15670 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15671 { } /* end */
15672};
15673
15674/*
15675 * 6ch mode
15676 */
15677static struct hda_verb alc662_sixstack_ch8_init[] = {
15678 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15679 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15680 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15681 { } /* end */
15682};
15683
15684static struct hda_channel_mode alc662_5stack_modes[2] = {
15685 { 2, alc662_sixstack_ch6_init },
15686 { 6, alc662_sixstack_ch8_init },
15687};
15688
15689/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15690 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15691 */
15692
15693static struct snd_kcontrol_new alc662_base_mixer[] = {
15694 /* output mixer control */
15695 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 15696 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15697 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 15698 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15699 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15700 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15701 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15702 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15704
15705 /*Input mixer control */
15706 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15707 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15708 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15709 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15710 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15711 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15712 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15713 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
15714 { } /* end */
15715};
15716
15717static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15718 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15719 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
15720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15721 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15722 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15723 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15724 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15727 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15728 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15729 { } /* end */
15730};
15731
15732static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15733 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15734 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15735 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 15736 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15737 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15738 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15739 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15740 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15741 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15742 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15743 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15744 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15745 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15748 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15749 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15750 { } /* end */
15751};
15752
15753static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15754 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15755 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
15756 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15757 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
15758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15759 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15760 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15763 { } /* end */
15764};
15765
291702f0 15766static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
15767 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15768 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
15769
15770 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15771 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15772 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15773
15774 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15775 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15776 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15777 { } /* end */
15778};
15779
8c427226 15780static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
15781 ALC262_HIPPO_MASTER_SWITCH,
15782 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 15783 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
15784 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15785 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
15786 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15787 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15788 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15791 { } /* end */
15792};
15793
f1d4e28b
KY
15794static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15795 .ops = &snd_hda_bind_vol,
15796 .values = {
15797 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15798 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15799 0
15800 },
15801};
15802
15803static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15804 .ops = &snd_hda_bind_sw,
15805 .values = {
15806 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15807 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15808 0
15809 },
15810};
15811
6dda9f4a 15812static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
15813 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15814 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15815 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15817 { } /* end */
15818};
15819
15820static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15821 .ops = &snd_hda_bind_sw,
15822 .values = {
15823 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15824 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15825 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15826 0
15827 },
15828};
15829
15830static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15831 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15832 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15835 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15836 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15837
15838 { } /* end */
15839};
15840
15841static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15842 .ops = &snd_hda_bind_sw,
15843 .values = {
15844 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15845 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15846 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15847 0
15848 },
15849};
15850
15851static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15852 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15853 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15856 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15857 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15858 { } /* end */
15859};
15860
15861static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
15862 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15863 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
15864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15866 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15867 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15868 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15869 { } /* end */
15870};
15871
15872static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15873 .ops = &snd_hda_bind_vol,
15874 .values = {
15875 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15876 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15877 0
15878 },
15879};
15880
15881static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15882 .ops = &snd_hda_bind_sw,
15883 .values = {
15884 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15885 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15886 0
15887 },
15888};
15889
15890static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15891 HDA_BIND_VOL("Master Playback Volume",
15892 &alc663_asus_two_bind_master_vol),
15893 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15894 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
15895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
15898 { } /* end */
15899};
15900
15901static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15902 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15903 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15904 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15906 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
15908 { } /* end */
15909};
15910
15911static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15912 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15913 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15914 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15915 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15916 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15917
15918 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15919 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15920 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15921 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15922 { } /* end */
15923};
15924
15925static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15926 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15927 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15929
15930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15932 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15933 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15936 { } /* end */
15937};
15938
bc9f98a9
KY
15939static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15940 {
15941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15942 .name = "Channel Mode",
15943 .info = alc_ch_mode_info,
15944 .get = alc_ch_mode_get,
15945 .put = alc_ch_mode_put,
15946 },
15947 { } /* end */
15948};
15949
15950static struct hda_verb alc662_init_verbs[] = {
15951 /* ADC: mute amp left and right */
15952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15953 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15954 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15955
cb53c626
TI
15956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15961
b60dd394
KY
15962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15964 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15966 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15968
15969 /* Front Pin: output 0 (0x0c) */
15970 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15971 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15972
15973 /* Rear Pin: output 1 (0x0d) */
15974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15975 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15976
15977 /* CLFE Pin: output 2 (0x0e) */
15978 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15979 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15980
15981 /* Mic (rear) pin: input vref at 80% */
15982 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15983 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15984 /* Front Mic pin: input vref at 80% */
15985 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15986 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15987 /* Line In pin: input */
15988 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15989 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15990 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15991 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15992 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15993 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15994 /* CD pin widget for input */
15995 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15996
15997 /* FIXME: use matrix-type input source selection */
15998 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15999 /* Input mixer */
16000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 16001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
16002
16003 /* always trun on EAPD */
16004 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16005 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16006
bc9f98a9
KY
16007 { }
16008};
16009
16010static struct hda_verb alc662_sue_init_verbs[] = {
16011 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16012 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
16013 {}
16014};
16015
16016static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16017 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16019 {}
bc9f98a9
KY
16020};
16021
8c427226
KY
16022/* Set Unsolicited Event*/
16023static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16024 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16025 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16026 {}
16027};
16028
bc9f98a9
KY
16029/*
16030 * generic initialization of ADC, input mixers and output mixers
16031 */
16032static struct hda_verb alc662_auto_init_verbs[] = {
16033 /*
16034 * Unmute ADC and set the default input to mic-in
16035 */
16036 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16037 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16038
16039 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16040 * mixer widget
16041 * Note: PASD motherboards uses the Line In 2 as the input for front
16042 * panel mic (mic 2)
16043 */
16044 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16045 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16046 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16047 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16048 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16049 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
16050
16051 /*
16052 * Set up output mixers (0x0c - 0x0f)
16053 */
16054 /* set vol=0 to output mixers */
16055 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16056 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16057 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16058
16059 /* set up input amps for analog loopback */
16060 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
16061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
16067
16068
16069 /* FIXME: use matrix-type input source selection */
16070 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16071 /* Input mixer */
16072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 16073 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
16074 { }
16075};
16076
24fb9173
TI
16077/* additional verbs for ALC663 */
16078static struct hda_verb alc663_auto_init_verbs[] = {
16079 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16080 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16081 { }
16082};
16083
6dda9f4a 16084static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
16085 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16086 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
16087 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16088 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
16089 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16092 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16093 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16094 {}
16095};
16096
16097static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16098 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16099 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16100 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16103 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16104 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16105 {}
16106};
16107
16108static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16110 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16111 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16112 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16114 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16115 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16116 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16117 {}
16118};
6dda9f4a 16119
f1d4e28b
KY
16120static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16121 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16123 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16126 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16128 {}
16129};
6dda9f4a 16130
f1d4e28b
KY
16131static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16132 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16133 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16134 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16135 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16136 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16137 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16138 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
16141 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16142 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
16143 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16144 {}
16145};
16146
16147static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16150 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16151 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16153 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16154 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16159 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
16160 {}
16161};
16162
16163static struct hda_verb alc663_g71v_init_verbs[] = {
16164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16165 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16166 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16167
16168 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16169 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16170 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16171
16172 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16173 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16174 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16175 {}
16176};
16177
16178static struct hda_verb alc663_g50v_init_verbs[] = {
16179 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16180 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16181 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16182
16183 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16184 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16185 {}
16186};
16187
f1d4e28b
KY
16188static struct hda_verb alc662_ecs_init_verbs[] = {
16189 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16190 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16191 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16192 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16193 {}
16194};
16195
622e84cd
KY
16196static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16197 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16198 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16200 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16201 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16202 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16203 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16204 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16205 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16206 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16207 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16208 {}
16209};
16210
16211static struct hda_verb alc272_dell_init_verbs[] = {
16212 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16213 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16215 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16216 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16217 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16218 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16221 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16222 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16223 {}
16224};
16225
f1d4e28b
KY
16226static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16227 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16228 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16229 { } /* end */
16230};
16231
622e84cd
KY
16232static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16233 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16234 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16235 { } /* end */
16236};
16237
bc9f98a9
KY
16238static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16239{
16240 unsigned int present;
f12ab1e0 16241 unsigned char bits;
bc9f98a9
KY
16242
16243 present = snd_hda_codec_read(codec, 0x14, 0,
16244 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
16245 bits = present ? HDA_AMP_MUTE : 0;
16246 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16247 HDA_AMP_MUTE, bits);
bc9f98a9
KY
16248}
16249
16250static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16251{
16252 unsigned int present;
f12ab1e0 16253 unsigned char bits;
bc9f98a9
KY
16254
16255 present = snd_hda_codec_read(codec, 0x1b, 0,
16256 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
16257 bits = present ? HDA_AMP_MUTE : 0;
16258 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16259 HDA_AMP_MUTE, bits);
16260 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16261 HDA_AMP_MUTE, bits);
bc9f98a9
KY
16262}
16263
16264static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16265 unsigned int res)
16266{
16267 if ((res >> 26) == ALC880_HP_EVENT)
16268 alc662_lenovo_101e_all_automute(codec);
16269 if ((res >> 26) == ALC880_FRONT_EVENT)
16270 alc662_lenovo_101e_ispeaker_automute(codec);
16271}
16272
291702f0
KY
16273/* unsolicited event for HP jack sensing */
16274static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16275 unsigned int res)
16276{
291702f0 16277 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 16278 alc_mic_automute(codec);
42171c17
TI
16279 else
16280 alc262_hippo_unsol_event(codec, res);
291702f0
KY
16281}
16282
4f5d1706
TI
16283static void alc662_eeepc_setup(struct hda_codec *codec)
16284{
16285 struct alc_spec *spec = codec->spec;
16286
16287 alc262_hippo1_setup(codec);
16288 spec->ext_mic.pin = 0x18;
16289 spec->ext_mic.mux_idx = 0;
16290 spec->int_mic.pin = 0x19;
16291 spec->int_mic.mux_idx = 1;
16292 spec->auto_mic = 1;
16293}
16294
291702f0
KY
16295static void alc662_eeepc_inithook(struct hda_codec *codec)
16296{
4f5d1706
TI
16297 alc262_hippo_automute(codec);
16298 alc_mic_automute(codec);
291702f0
KY
16299}
16300
4f5d1706 16301static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 16302{
42171c17
TI
16303 struct alc_spec *spec = codec->spec;
16304
16305 spec->autocfg.hp_pins[0] = 0x14;
16306 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
16307}
16308
4f5d1706
TI
16309#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
16310
6dda9f4a
KY
16311static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16312{
16313 unsigned int present;
16314 unsigned char bits;
16315
16316 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
16317 AC_VERB_GET_PIN_SENSE, 0)
16318 & AC_PINSENSE_PRESENCE;
6dda9f4a 16319 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
16320 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16321 AMP_IN_MUTE(0), bits);
16322 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16323 AMP_IN_MUTE(0), bits);
16324}
16325
16326static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16327{
16328 unsigned int present;
16329 unsigned char bits;
16330
16331 present = snd_hda_codec_read(codec, 0x21, 0,
16332 AC_VERB_GET_PIN_SENSE, 0)
16333 & AC_PINSENSE_PRESENCE;
16334 bits = present ? HDA_AMP_MUTE : 0;
16335 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16336 AMP_IN_MUTE(0), bits);
16337 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16338 AMP_IN_MUTE(0), bits);
16339 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16340 AMP_IN_MUTE(0), bits);
16341 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16342 AMP_IN_MUTE(0), bits);
16343}
16344
16345static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16346{
16347 unsigned int present;
16348 unsigned char bits;
16349
16350 present = snd_hda_codec_read(codec, 0x15, 0,
16351 AC_VERB_GET_PIN_SENSE, 0)
16352 & AC_PINSENSE_PRESENCE;
16353 bits = present ? HDA_AMP_MUTE : 0;
16354 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16355 AMP_IN_MUTE(0), bits);
16356 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16357 AMP_IN_MUTE(0), bits);
16358 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16359 AMP_IN_MUTE(0), bits);
16360 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16361 AMP_IN_MUTE(0), bits);
16362}
16363
16364static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16365{
16366 unsigned int present;
16367 unsigned char bits;
16368
16369 present = snd_hda_codec_read(codec, 0x1b, 0,
16370 AC_VERB_GET_PIN_SENSE, 0)
16371 & AC_PINSENSE_PRESENCE;
16372 bits = present ? 0 : PIN_OUT;
16373 snd_hda_codec_write(codec, 0x14, 0,
16374 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16375}
16376
16377static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16378{
16379 unsigned int present1, present2;
16380
16381 present1 = snd_hda_codec_read(codec, 0x21, 0,
16382 AC_VERB_GET_PIN_SENSE, 0)
16383 & AC_PINSENSE_PRESENCE;
16384 present2 = snd_hda_codec_read(codec, 0x15, 0,
16385 AC_VERB_GET_PIN_SENSE, 0)
16386 & AC_PINSENSE_PRESENCE;
16387
16388 if (present1 || present2) {
16389 snd_hda_codec_write_cache(codec, 0x14, 0,
16390 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16391 } else {
16392 snd_hda_codec_write_cache(codec, 0x14, 0,
16393 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16394 }
16395}
16396
16397static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16398{
16399 unsigned int present1, present2;
16400
16401 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16402 AC_VERB_GET_PIN_SENSE, 0)
16403 & AC_PINSENSE_PRESENCE;
16404 present2 = snd_hda_codec_read(codec, 0x15, 0,
16405 AC_VERB_GET_PIN_SENSE, 0)
16406 & AC_PINSENSE_PRESENCE;
16407
16408 if (present1 || present2) {
16409 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16410 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16411 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16412 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16413 } else {
16414 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16415 AMP_IN_MUTE(0), 0);
16416 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16417 AMP_IN_MUTE(0), 0);
16418 }
6dda9f4a
KY
16419}
16420
6dda9f4a
KY
16421static void alc663_m51va_unsol_event(struct hda_codec *codec,
16422 unsigned int res)
16423{
16424 switch (res >> 26) {
16425 case ALC880_HP_EVENT:
16426 alc663_m51va_speaker_automute(codec);
16427 break;
16428 case ALC880_MIC_EVENT:
4f5d1706 16429 alc_mic_automute(codec);
6dda9f4a
KY
16430 break;
16431 }
16432}
16433
4f5d1706
TI
16434static void alc663_m51va_setup(struct hda_codec *codec)
16435{
16436 struct alc_spec *spec = codec->spec;
16437 spec->ext_mic.pin = 0x18;
16438 spec->ext_mic.mux_idx = 0;
16439 spec->int_mic.pin = 0x12;
16440 spec->int_mic.mux_idx = 1;
16441 spec->auto_mic = 1;
16442}
16443
6dda9f4a
KY
16444static void alc663_m51va_inithook(struct hda_codec *codec)
16445{
16446 alc663_m51va_speaker_automute(codec);
4f5d1706 16447 alc_mic_automute(codec);
6dda9f4a
KY
16448}
16449
f1d4e28b 16450/* ***************** Mode1 ******************************/
4f5d1706
TI
16451#define alc663_mode1_unsol_event alc663_m51va_unsol_event
16452#define alc663_mode1_setup alc663_m51va_setup
16453#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 16454
f1d4e28b
KY
16455/* ***************** Mode2 ******************************/
16456static void alc662_mode2_unsol_event(struct hda_codec *codec,
16457 unsigned int res)
16458{
16459 switch (res >> 26) {
16460 case ALC880_HP_EVENT:
16461 alc662_f5z_speaker_automute(codec);
16462 break;
16463 case ALC880_MIC_EVENT:
4f5d1706 16464 alc_mic_automute(codec);
f1d4e28b
KY
16465 break;
16466 }
16467}
16468
4f5d1706
TI
16469#define alc662_mode2_setup alc663_m51va_setup
16470
f1d4e28b
KY
16471static void alc662_mode2_inithook(struct hda_codec *codec)
16472{
16473 alc662_f5z_speaker_automute(codec);
4f5d1706 16474 alc_mic_automute(codec);
f1d4e28b
KY
16475}
16476/* ***************** Mode3 ******************************/
16477static void alc663_mode3_unsol_event(struct hda_codec *codec,
16478 unsigned int res)
16479{
16480 switch (res >> 26) {
16481 case ALC880_HP_EVENT:
16482 alc663_two_hp_m1_speaker_automute(codec);
16483 break;
16484 case ALC880_MIC_EVENT:
4f5d1706 16485 alc_mic_automute(codec);
f1d4e28b
KY
16486 break;
16487 }
16488}
16489
4f5d1706
TI
16490#define alc663_mode3_setup alc663_m51va_setup
16491
f1d4e28b
KY
16492static void alc663_mode3_inithook(struct hda_codec *codec)
16493{
16494 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 16495 alc_mic_automute(codec);
f1d4e28b
KY
16496}
16497/* ***************** Mode4 ******************************/
16498static void alc663_mode4_unsol_event(struct hda_codec *codec,
16499 unsigned int res)
16500{
16501 switch (res >> 26) {
16502 case ALC880_HP_EVENT:
16503 alc663_21jd_two_speaker_automute(codec);
16504 break;
16505 case ALC880_MIC_EVENT:
4f5d1706 16506 alc_mic_automute(codec);
f1d4e28b
KY
16507 break;
16508 }
16509}
16510
4f5d1706
TI
16511#define alc663_mode4_setup alc663_m51va_setup
16512
f1d4e28b
KY
16513static void alc663_mode4_inithook(struct hda_codec *codec)
16514{
16515 alc663_21jd_two_speaker_automute(codec);
4f5d1706 16516 alc_mic_automute(codec);
f1d4e28b
KY
16517}
16518/* ***************** Mode5 ******************************/
16519static void alc663_mode5_unsol_event(struct hda_codec *codec,
16520 unsigned int res)
16521{
16522 switch (res >> 26) {
16523 case ALC880_HP_EVENT:
16524 alc663_15jd_two_speaker_automute(codec);
16525 break;
16526 case ALC880_MIC_EVENT:
4f5d1706 16527 alc_mic_automute(codec);
f1d4e28b
KY
16528 break;
16529 }
16530}
16531
4f5d1706
TI
16532#define alc663_mode5_setup alc663_m51va_setup
16533
f1d4e28b
KY
16534static void alc663_mode5_inithook(struct hda_codec *codec)
16535{
16536 alc663_15jd_two_speaker_automute(codec);
4f5d1706 16537 alc_mic_automute(codec);
f1d4e28b
KY
16538}
16539/* ***************** Mode6 ******************************/
16540static void alc663_mode6_unsol_event(struct hda_codec *codec,
16541 unsigned int res)
16542{
16543 switch (res >> 26) {
16544 case ALC880_HP_EVENT:
16545 alc663_two_hp_m2_speaker_automute(codec);
16546 break;
16547 case ALC880_MIC_EVENT:
4f5d1706 16548 alc_mic_automute(codec);
f1d4e28b
KY
16549 break;
16550 }
16551}
16552
4f5d1706
TI
16553#define alc663_mode6_setup alc663_m51va_setup
16554
f1d4e28b
KY
16555static void alc663_mode6_inithook(struct hda_codec *codec)
16556{
16557 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 16558 alc_mic_automute(codec);
f1d4e28b
KY
16559}
16560
6dda9f4a
KY
16561static void alc663_g71v_hp_automute(struct hda_codec *codec)
16562{
16563 unsigned int present;
16564 unsigned char bits;
16565
16566 present = snd_hda_codec_read(codec, 0x21, 0,
16567 AC_VERB_GET_PIN_SENSE, 0)
16568 & AC_PINSENSE_PRESENCE;
16569 bits = present ? HDA_AMP_MUTE : 0;
16570 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16571 HDA_AMP_MUTE, bits);
16572 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16573 HDA_AMP_MUTE, bits);
16574}
16575
16576static void alc663_g71v_front_automute(struct hda_codec *codec)
16577{
16578 unsigned int present;
16579 unsigned char bits;
16580
16581 present = snd_hda_codec_read(codec, 0x15, 0,
16582 AC_VERB_GET_PIN_SENSE, 0)
16583 & AC_PINSENSE_PRESENCE;
16584 bits = present ? HDA_AMP_MUTE : 0;
16585 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16586 HDA_AMP_MUTE, bits);
16587}
16588
16589static void alc663_g71v_unsol_event(struct hda_codec *codec,
16590 unsigned int res)
16591{
16592 switch (res >> 26) {
16593 case ALC880_HP_EVENT:
16594 alc663_g71v_hp_automute(codec);
16595 break;
16596 case ALC880_FRONT_EVENT:
16597 alc663_g71v_front_automute(codec);
16598 break;
16599 case ALC880_MIC_EVENT:
4f5d1706 16600 alc_mic_automute(codec);
6dda9f4a
KY
16601 break;
16602 }
16603}
16604
4f5d1706
TI
16605#define alc663_g71v_setup alc663_m51va_setup
16606
6dda9f4a
KY
16607static void alc663_g71v_inithook(struct hda_codec *codec)
16608{
16609 alc663_g71v_front_automute(codec);
16610 alc663_g71v_hp_automute(codec);
4f5d1706 16611 alc_mic_automute(codec);
6dda9f4a
KY
16612}
16613
16614static void alc663_g50v_unsol_event(struct hda_codec *codec,
16615 unsigned int res)
16616{
16617 switch (res >> 26) {
16618 case ALC880_HP_EVENT:
16619 alc663_m51va_speaker_automute(codec);
16620 break;
16621 case ALC880_MIC_EVENT:
4f5d1706 16622 alc_mic_automute(codec);
6dda9f4a
KY
16623 break;
16624 }
16625}
16626
4f5d1706
TI
16627#define alc663_g50v_setup alc663_m51va_setup
16628
6dda9f4a
KY
16629static void alc663_g50v_inithook(struct hda_codec *codec)
16630{
16631 alc663_m51va_speaker_automute(codec);
4f5d1706 16632 alc_mic_automute(codec);
6dda9f4a
KY
16633}
16634
f1d4e28b
KY
16635static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16636 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 16637 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
16638
16639 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16640 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16641 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16642
16643 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16644 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16645 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16646 { } /* end */
16647};
16648
9541ba1d
CP
16649static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16650 /* Master Playback automatically created from Speaker and Headphone */
16651 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16652 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16654 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16655
16656 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16657 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16658 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16659
16660 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16661 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16662 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16663 { } /* end */
16664};
16665
cb53c626
TI
16666#ifdef CONFIG_SND_HDA_POWER_SAVE
16667#define alc662_loopbacks alc880_loopbacks
16668#endif
16669
bc9f98a9 16670
def319f9 16671/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
16672#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16673#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16674#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16675#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16676
16677/*
16678 * configuration and preset
16679 */
16680static const char *alc662_models[ALC662_MODEL_LAST] = {
16681 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16682 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16683 [ALC662_3ST_6ch] = "3stack-6ch",
16684 [ALC662_5ST_DIG] = "6stack-dig",
16685 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 16686 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 16687 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 16688 [ALC662_ECS] = "ecs",
6dda9f4a
KY
16689 [ALC663_ASUS_M51VA] = "m51va",
16690 [ALC663_ASUS_G71V] = "g71v",
16691 [ALC663_ASUS_H13] = "h13",
16692 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
16693 [ALC663_ASUS_MODE1] = "asus-mode1",
16694 [ALC662_ASUS_MODE2] = "asus-mode2",
16695 [ALC663_ASUS_MODE3] = "asus-mode3",
16696 [ALC663_ASUS_MODE4] = "asus-mode4",
16697 [ALC663_ASUS_MODE5] = "asus-mode5",
16698 [ALC663_ASUS_MODE6] = "asus-mode6",
01f2bd48
TI
16699 [ALC272_DELL] = "dell",
16700 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 16701 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
16702 [ALC662_AUTO] = "auto",
16703};
16704
16705static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 16706 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
16707 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16708 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 16709 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509
TI
16710 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16711 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 16712 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 16713 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 16714 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16715 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16716 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16717 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16718 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16719 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16720 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd
KY
16721 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16722 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16723 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 16724 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16725 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16726 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16727 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 16728 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 16729 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16730 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16731 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16732 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 16733 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 16734 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd
KY
16735 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16736 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16737 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
16738 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16739 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16740 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 16741 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
16742 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16743 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 16744 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
16745 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16746 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16747 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16748 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16749 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 16750 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 16751 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16752 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
16753 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16754 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16755 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16756 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
16757 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16758 ALC662_3ST_6ch_DIG),
9541ba1d 16759 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
16760 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16761 ALC662_3ST_6ch_DIG),
19c009aa 16762 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 16763 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 16764 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 16765 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 16766 ALC662_3ST_6ch_DIG),
dea0a509
TI
16767 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16768 ALC663_ASUS_H13),
bc9f98a9
KY
16769 {}
16770};
16771
16772static struct alc_config_preset alc662_presets[] = {
16773 [ALC662_3ST_2ch_DIG] = {
f9e336f6 16774 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
16775 .init_verbs = { alc662_init_verbs },
16776 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16777 .dac_nids = alc662_dac_nids,
16778 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16779 .dig_in_nid = ALC662_DIGIN_NID,
16780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16781 .channel_mode = alc662_3ST_2ch_modes,
16782 .input_mux = &alc662_capture_source,
16783 },
16784 [ALC662_3ST_6ch_DIG] = {
f9e336f6 16785 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16786 .init_verbs = { alc662_init_verbs },
16787 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16788 .dac_nids = alc662_dac_nids,
16789 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16790 .dig_in_nid = ALC662_DIGIN_NID,
16791 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16792 .channel_mode = alc662_3ST_6ch_modes,
16793 .need_dac_fix = 1,
16794 .input_mux = &alc662_capture_source,
f12ab1e0 16795 },
bc9f98a9 16796 [ALC662_3ST_6ch] = {
f9e336f6 16797 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16798 .init_verbs = { alc662_init_verbs },
16799 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16800 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16801 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16802 .channel_mode = alc662_3ST_6ch_modes,
16803 .need_dac_fix = 1,
16804 .input_mux = &alc662_capture_source,
f12ab1e0 16805 },
bc9f98a9 16806 [ALC662_5ST_DIG] = {
f9e336f6 16807 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16808 .init_verbs = { alc662_init_verbs },
16809 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16810 .dac_nids = alc662_dac_nids,
16811 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16812 .dig_in_nid = ALC662_DIGIN_NID,
16813 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16814 .channel_mode = alc662_5stack_modes,
16815 .input_mux = &alc662_capture_source,
16816 },
16817 [ALC662_LENOVO_101E] = {
f9e336f6 16818 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
16819 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16820 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16821 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16822 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16823 .channel_mode = alc662_3ST_2ch_modes,
16824 .input_mux = &alc662_lenovo_101e_capture_source,
16825 .unsol_event = alc662_lenovo_101e_unsol_event,
16826 .init_hook = alc662_lenovo_101e_all_automute,
16827 },
291702f0 16828 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 16829 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
16830 .init_verbs = { alc662_init_verbs,
16831 alc662_eeepc_sue_init_verbs },
16832 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16833 .dac_nids = alc662_dac_nids,
291702f0
KY
16834 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16835 .channel_mode = alc662_3ST_2ch_modes,
291702f0 16836 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 16837 .setup = alc662_eeepc_setup,
291702f0
KY
16838 .init_hook = alc662_eeepc_inithook,
16839 },
8c427226 16840 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 16841 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
16842 alc662_chmode_mixer },
16843 .init_verbs = { alc662_init_verbs,
16844 alc662_eeepc_ep20_sue_init_verbs },
16845 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16846 .dac_nids = alc662_dac_nids,
8c427226
KY
16847 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16848 .channel_mode = alc662_3ST_6ch_modes,
16849 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 16850 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 16851 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
16852 .init_hook = alc662_eeepc_ep20_inithook,
16853 },
f1d4e28b 16854 [ALC662_ECS] = {
f9e336f6 16855 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
16856 .init_verbs = { alc662_init_verbs,
16857 alc662_ecs_init_verbs },
16858 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16859 .dac_nids = alc662_dac_nids,
16860 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16861 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16862 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 16863 .setup = alc662_eeepc_setup,
f1d4e28b
KY
16864 .init_hook = alc662_eeepc_inithook,
16865 },
6dda9f4a 16866 [ALC663_ASUS_M51VA] = {
f9e336f6 16867 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16868 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16869 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16870 .dac_nids = alc662_dac_nids,
16871 .dig_out_nid = ALC662_DIGOUT_NID,
16872 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16873 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 16874 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 16875 .setup = alc663_m51va_setup,
6dda9f4a
KY
16876 .init_hook = alc663_m51va_inithook,
16877 },
16878 [ALC663_ASUS_G71V] = {
f9e336f6 16879 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
16880 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16881 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16882 .dac_nids = alc662_dac_nids,
16883 .dig_out_nid = ALC662_DIGOUT_NID,
16884 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16885 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 16886 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 16887 .setup = alc663_g71v_setup,
6dda9f4a
KY
16888 .init_hook = alc663_g71v_inithook,
16889 },
16890 [ALC663_ASUS_H13] = {
f9e336f6 16891 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16892 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16893 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16894 .dac_nids = alc662_dac_nids,
16895 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16896 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
16897 .unsol_event = alc663_m51va_unsol_event,
16898 .init_hook = alc663_m51va_inithook,
16899 },
16900 [ALC663_ASUS_G50V] = {
f9e336f6 16901 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
16902 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16903 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16904 .dac_nids = alc662_dac_nids,
16905 .dig_out_nid = ALC662_DIGOUT_NID,
16906 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16907 .channel_mode = alc662_3ST_6ch_modes,
16908 .input_mux = &alc663_capture_source,
16909 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 16910 .setup = alc663_g50v_setup,
6dda9f4a
KY
16911 .init_hook = alc663_g50v_inithook,
16912 },
f1d4e28b 16913 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
16914 .mixers = { alc663_m51va_mixer },
16915 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16916 .init_verbs = { alc662_init_verbs,
16917 alc663_21jd_amic_init_verbs },
16918 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16919 .hp_nid = 0x03,
16920 .dac_nids = alc662_dac_nids,
16921 .dig_out_nid = ALC662_DIGOUT_NID,
16922 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16923 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16924 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 16925 .setup = alc663_mode1_setup,
f1d4e28b
KY
16926 .init_hook = alc663_mode1_inithook,
16927 },
16928 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
16929 .mixers = { alc662_1bjd_mixer },
16930 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16931 .init_verbs = { alc662_init_verbs,
16932 alc662_1bjd_amic_init_verbs },
16933 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16934 .dac_nids = alc662_dac_nids,
16935 .dig_out_nid = ALC662_DIGOUT_NID,
16936 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16937 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16938 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 16939 .setup = alc662_mode2_setup,
f1d4e28b
KY
16940 .init_hook = alc662_mode2_inithook,
16941 },
16942 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
16943 .mixers = { alc663_two_hp_m1_mixer },
16944 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16945 .init_verbs = { alc662_init_verbs,
16946 alc663_two_hp_amic_m1_init_verbs },
16947 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16948 .hp_nid = 0x03,
16949 .dac_nids = alc662_dac_nids,
16950 .dig_out_nid = ALC662_DIGOUT_NID,
16951 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16952 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16953 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 16954 .setup = alc663_mode3_setup,
f1d4e28b
KY
16955 .init_hook = alc663_mode3_inithook,
16956 },
16957 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
16958 .mixers = { alc663_asus_21jd_clfe_mixer },
16959 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16960 .init_verbs = { alc662_init_verbs,
16961 alc663_21jd_amic_init_verbs},
16962 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16963 .hp_nid = 0x03,
16964 .dac_nids = alc662_dac_nids,
16965 .dig_out_nid = ALC662_DIGOUT_NID,
16966 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16967 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16968 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 16969 .setup = alc663_mode4_setup,
f1d4e28b
KY
16970 .init_hook = alc663_mode4_inithook,
16971 },
16972 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
16973 .mixers = { alc663_asus_15jd_clfe_mixer },
16974 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16975 .init_verbs = { alc662_init_verbs,
16976 alc663_15jd_amic_init_verbs },
16977 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16978 .hp_nid = 0x03,
16979 .dac_nids = alc662_dac_nids,
16980 .dig_out_nid = ALC662_DIGOUT_NID,
16981 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16982 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16983 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 16984 .setup = alc663_mode5_setup,
f1d4e28b
KY
16985 .init_hook = alc663_mode5_inithook,
16986 },
16987 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
16988 .mixers = { alc663_two_hp_m2_mixer },
16989 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16990 .init_verbs = { alc662_init_verbs,
16991 alc663_two_hp_amic_m2_init_verbs },
16992 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16993 .hp_nid = 0x03,
16994 .dac_nids = alc662_dac_nids,
16995 .dig_out_nid = ALC662_DIGOUT_NID,
16996 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16997 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 16998 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 16999 .setup = alc663_mode6_setup,
f1d4e28b
KY
17000 .init_hook = alc663_mode6_inithook,
17001 },
622e84cd
KY
17002 [ALC272_DELL] = {
17003 .mixers = { alc663_m51va_mixer },
17004 .cap_mixer = alc272_auto_capture_mixer,
17005 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17006 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17007 .dac_nids = alc662_dac_nids,
17008 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17009 .adc_nids = alc272_adc_nids,
17010 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17011 .capsrc_nids = alc272_capsrc_nids,
17012 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 17013 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17014 .setup = alc663_m51va_setup,
622e84cd
KY
17015 .init_hook = alc663_m51va_inithook,
17016 },
17017 [ALC272_DELL_ZM1] = {
17018 .mixers = { alc663_m51va_mixer },
17019 .cap_mixer = alc662_auto_capture_mixer,
17020 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17021 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17022 .dac_nids = alc662_dac_nids,
17023 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17024 .adc_nids = alc662_adc_nids,
b59bdf3b 17025 .num_adc_nids = 1,
622e84cd
KY
17026 .capsrc_nids = alc662_capsrc_nids,
17027 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 17028 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17029 .setup = alc663_m51va_setup,
622e84cd
KY
17030 .init_hook = alc663_m51va_inithook,
17031 },
9541ba1d
CP
17032 [ALC272_SAMSUNG_NC10] = {
17033 .mixers = { alc272_nc10_mixer },
17034 .init_verbs = { alc662_init_verbs,
17035 alc663_21jd_amic_init_verbs },
17036 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17037 .dac_nids = alc272_dac_nids,
17038 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17039 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 17040 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 17041 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 17042 .setup = alc663_mode4_setup,
9541ba1d
CP
17043 .init_hook = alc663_mode4_inithook,
17044 },
bc9f98a9
KY
17045};
17046
17047
17048/*
17049 * BIOS auto configuration
17050 */
17051
17052/* add playback controls from the parsed DAC table */
17053static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
17054 const struct auto_pin_cfg *cfg)
17055{
17056 char name[32];
17057 static const char *chname[4] = {
17058 "Front", "Surround", NULL /*CLFE*/, "Side"
17059 };
17060 hda_nid_t nid;
17061 int i, err;
17062
17063 for (i = 0; i < cfg->line_outs; i++) {
17064 if (!spec->multiout.dac_nids[i])
17065 continue;
b60dd394 17066 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
17067 if (i == 2) {
17068 /* Center/LFE */
17069 err = add_control(spec, ALC_CTL_WIDGET_VOL,
17070 "Center Playback Volume",
f12ab1e0
TI
17071 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
17072 HDA_OUTPUT));
bc9f98a9
KY
17073 if (err < 0)
17074 return err;
17075 err = add_control(spec, ALC_CTL_WIDGET_VOL,
17076 "LFE Playback Volume",
f12ab1e0
TI
17077 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
17078 HDA_OUTPUT));
bc9f98a9
KY
17079 if (err < 0)
17080 return err;
b69ce01a 17081 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 17082 "Center Playback Switch",
b69ce01a 17083 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 17084 HDA_INPUT));
bc9f98a9
KY
17085 if (err < 0)
17086 return err;
b69ce01a 17087 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 17088 "LFE Playback Switch",
b69ce01a 17089 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 17090 HDA_INPUT));
bc9f98a9
KY
17091 if (err < 0)
17092 return err;
17093 } else {
0d884cb9
TI
17094 const char *pfx;
17095 if (cfg->line_outs == 1 &&
17096 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17097 if (!cfg->hp_pins)
17098 pfx = "Speaker";
17099 else
17100 pfx = "PCM";
17101 } else
17102 pfx = chname[i];
17103 sprintf(name, "%s Playback Volume", pfx);
bc9f98a9 17104 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
17105 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
17106 HDA_OUTPUT));
bc9f98a9
KY
17107 if (err < 0)
17108 return err;
0d884cb9
TI
17109 if (cfg->line_outs == 1 &&
17110 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17111 pfx = "Speaker";
17112 sprintf(name, "%s Playback Switch", pfx);
b69ce01a
HRK
17113 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17114 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
17115 3, 0, HDA_INPUT));
bc9f98a9
KY
17116 if (err < 0)
17117 return err;
17118 }
17119 }
17120 return 0;
17121}
17122
17123/* add playback controls for speaker and HP outputs */
17124static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
17125 const char *pfx)
17126{
17127 hda_nid_t nid;
17128 int err;
17129 char name[32];
17130
17131 if (!pin)
17132 return 0;
17133
24fb9173
TI
17134 if (pin == 0x17) {
17135 /* ALC663 has a mono output pin on 0x17 */
17136 sprintf(name, "%s Playback Switch", pfx);
17137 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17138 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
17139 return err;
17140 }
17141
bc9f98a9
KY
17142 if (alc880_is_fixed_pin(pin)) {
17143 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
939778ae 17144 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
bc9f98a9
KY
17145 /* specify the DAC as the extra output */
17146 if (!spec->multiout.hp_nid)
17147 spec->multiout.hp_nid = nid;
17148 else
17149 spec->multiout.extra_out_nid[0] = nid;
17150 /* control HP volume/switch on the output mixer amp */
17151 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17152 sprintf(name, "%s Playback Volume", pfx);
17153 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17154 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
17155 if (err < 0)
17156 return err;
17157 sprintf(name, "%s Playback Switch", pfx);
17158 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
17159 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
17160 if (err < 0)
17161 return err;
17162 } else if (alc880_is_multi_pin(pin)) {
17163 /* set manual connection */
17164 /* we have only a switch on HP-out PIN */
17165 sprintf(name, "%s Playback Switch", pfx);
17166 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17167 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17168 if (err < 0)
17169 return err;
17170 }
17171 return 0;
17172}
17173
17174/* create playback/capture controls for input pins */
05f5f477
TI
17175#define alc662_auto_create_input_ctls \
17176 alc880_auto_create_input_ctls
bc9f98a9
KY
17177
17178static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17179 hda_nid_t nid, int pin_type,
17180 int dac_idx)
17181{
f6c7e546 17182 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
17183 /* need the manual connection? */
17184 if (alc880_is_multi_pin(nid)) {
17185 struct alc_spec *spec = codec->spec;
17186 int idx = alc880_multi_pin_idx(nid);
17187 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
17188 AC_VERB_SET_CONNECT_SEL,
17189 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
17190 }
17191}
17192
17193static void alc662_auto_init_multi_out(struct hda_codec *codec)
17194{
17195 struct alc_spec *spec = codec->spec;
17196 int i;
17197
17198 for (i = 0; i <= HDA_SIDE; i++) {
17199 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17200 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 17201 if (nid)
baba8ee9 17202 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
17203 i);
17204 }
17205}
17206
17207static void alc662_auto_init_hp_out(struct hda_codec *codec)
17208{
17209 struct alc_spec *spec = codec->spec;
17210 hda_nid_t pin;
17211
17212 pin = spec->autocfg.hp_pins[0];
17213 if (pin) /* connect to front */
17214 /* use dac 0 */
17215 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17216 pin = spec->autocfg.speaker_pins[0];
17217 if (pin)
17218 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
17219}
17220
bc9f98a9
KY
17221#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17222
17223static void alc662_auto_init_analog_input(struct hda_codec *codec)
17224{
17225 struct alc_spec *spec = codec->spec;
17226 int i;
17227
17228 for (i = 0; i < AUTO_PIN_LAST; i++) {
17229 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 17230 if (alc_is_input_pin(codec, nid)) {
23f0c048 17231 alc_set_input_pin(codec, nid, i);
52ca15b7 17232 if (nid != ALC662_PIN_CD_NID &&
e82c025b 17233 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
17234 snd_hda_codec_write(codec, nid, 0,
17235 AC_VERB_SET_AMP_GAIN_MUTE,
17236 AMP_OUT_MUTE);
17237 }
17238 }
17239}
17240
f511b01c
TI
17241#define alc662_auto_init_input_src alc882_auto_init_input_src
17242
bc9f98a9
KY
17243static int alc662_parse_auto_config(struct hda_codec *codec)
17244{
17245 struct alc_spec *spec = codec->spec;
17246 int err;
17247 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17248
17249 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17250 alc662_ignore);
17251 if (err < 0)
17252 return err;
17253 if (!spec->autocfg.line_outs)
17254 return 0; /* can't find valid BIOS pin config */
17255
f12ab1e0
TI
17256 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17257 if (err < 0)
17258 return err;
17259 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17260 if (err < 0)
17261 return err;
17262 err = alc662_auto_create_extra_out(spec,
17263 spec->autocfg.speaker_pins[0],
17264 "Speaker");
17265 if (err < 0)
17266 return err;
17267 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17268 "Headphone");
17269 if (err < 0)
17270 return err;
05f5f477 17271 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17272 if (err < 0)
bc9f98a9
KY
17273 return err;
17274
17275 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17276
0852d7a6 17277 if (spec->autocfg.dig_outs)
bc9f98a9
KY
17278 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17279
603c4019 17280 if (spec->kctls.list)
d88897ea 17281 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
17282
17283 spec->num_mux_defs = 1;
61b9b9b1 17284 spec->input_mux = &spec->private_imux[0];
ea1fb29a 17285
d88897ea 17286 add_verb(spec, alc662_auto_init_verbs);
24fb9173 17287 if (codec->vendor_id == 0x10ec0663)
d88897ea 17288 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
17289
17290 err = alc_auto_add_mic_boost(codec);
17291 if (err < 0)
17292 return err;
17293
4a79ba34
TI
17294 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17295
8c87286f 17296 return 1;
bc9f98a9
KY
17297}
17298
17299/* additional initialization for auto-configuration model */
17300static void alc662_auto_init(struct hda_codec *codec)
17301{
f6c7e546 17302 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
17303 alc662_auto_init_multi_out(codec);
17304 alc662_auto_init_hp_out(codec);
17305 alc662_auto_init_analog_input(codec);
f511b01c 17306 alc662_auto_init_input_src(codec);
f6c7e546 17307 if (spec->unsol_event)
7fb0d78f 17308 alc_inithook(codec);
bc9f98a9
KY
17309}
17310
17311static int patch_alc662(struct hda_codec *codec)
17312{
17313 struct alc_spec *spec;
17314 int err, board_config;
17315
17316 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17317 if (!spec)
17318 return -ENOMEM;
17319
17320 codec->spec = spec;
17321
2c3bf9ab
TI
17322 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17323
bc9f98a9
KY
17324 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17325 alc662_models,
17326 alc662_cfg_tbl);
17327 if (board_config < 0) {
9a11f1aa
TI
17328 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17329 codec->chip_name);
bc9f98a9
KY
17330 board_config = ALC662_AUTO;
17331 }
17332
17333 if (board_config == ALC662_AUTO) {
17334 /* automatic parse from the BIOS config */
17335 err = alc662_parse_auto_config(codec);
17336 if (err < 0) {
17337 alc_free(codec);
17338 return err;
8c87286f 17339 } else if (!err) {
bc9f98a9
KY
17340 printk(KERN_INFO
17341 "hda_codec: Cannot set up configuration "
17342 "from BIOS. Using base mode...\n");
17343 board_config = ALC662_3ST_2ch_DIG;
17344 }
17345 }
17346
680cd536
KK
17347 err = snd_hda_attach_beep_device(codec, 0x1);
17348 if (err < 0) {
17349 alc_free(codec);
17350 return err;
17351 }
17352
bc9f98a9 17353 if (board_config != ALC662_AUTO)
e9c364c0 17354 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 17355
bc9f98a9
KY
17356 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17357 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17358
bc9f98a9
KY
17359 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17360 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17361
dd704698
TI
17362 if (!spec->adc_nids) {
17363 spec->adc_nids = alc662_adc_nids;
17364 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17365 }
17366 if (!spec->capsrc_nids)
17367 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 17368
f9e336f6 17369 if (!spec->cap_mixer)
b59bdf3b 17370 set_capture_mixer(codec);
b9591448
TI
17371 if (codec->vendor_id == 0x10ec0662)
17372 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17373 else
17374 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f9e336f6 17375
2134ea4f
TI
17376 spec->vmaster_nid = 0x02;
17377
bc9f98a9
KY
17378 codec->patch_ops = alc_patch_ops;
17379 if (board_config == ALC662_AUTO)
17380 spec->init_hook = alc662_auto_init;
cb53c626
TI
17381#ifdef CONFIG_SND_HDA_POWER_SAVE
17382 if (!spec->loopback.amplist)
17383 spec->loopback.amplist = alc662_loopbacks;
17384#endif
daead538 17385 codec->proc_widget_hook = print_realtek_coef;
bc9f98a9
KY
17386
17387 return 0;
17388}
17389
1da177e4
LT
17390/*
17391 * patch entries
17392 */
1289e9e8 17393static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 17394 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 17395 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 17396 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 17397 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 17398 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 17399 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 17400 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 17401 .patch = patch_alc861 },
f32610ed
JS
17402 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17403 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17404 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 17405 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 17406 .patch = patch_alc882 },
bc9f98a9
KY
17407 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17408 .patch = patch_alc662 },
6dda9f4a 17409 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 17410 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 17411 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 17412 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 17413 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 17414 .patch = patch_alc882 },
cb308f97 17415 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 17416 .patch = patch_alc882 },
df694daa 17417 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 17418 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 17419 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a
TI
17420 .patch = patch_alc882 },
17421 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17422 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
1da177e4
LT
17423 {} /* terminator */
17424};
1289e9e8
TI
17425
17426MODULE_ALIAS("snd-hda-codec-id:10ec*");
17427
17428MODULE_LICENSE("GPL");
17429MODULE_DESCRIPTION("Realtek HD-audio codec");
17430
17431static struct hda_codec_preset_list realtek_list = {
17432 .preset = snd_hda_preset_realtek,
17433 .owner = THIS_MODULE,
17434};
17435
17436static int __init patch_realtek_init(void)
17437{
17438 return snd_hda_add_codec_preset(&realtek_list);
17439}
17440
17441static void __exit patch_realtek_exit(void)
17442{
17443 snd_hda_delete_codec_preset(&realtek_list);
17444}
17445
17446module_init(patch_realtek_init)
17447module_exit(patch_realtek_exit)