]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix wrong model range check for ALC268
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
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,
84898e87
KY
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
26f5df26 138 ALC269_FUJITSU,
64154835 139 ALC269_LIFEBOOK,
f6a92248
KY
140 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */
142};
143
df694daa
KY
144/* ALC861 models */
145enum {
146 ALC861_3ST,
9c7f852e 147 ALC660_3ST,
df694daa
KY
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
22309c3e 150 ALC861_UNIWILL_M31,
a53d1aec 151 ALC861_TOSHIBA,
7cdbff94 152 ALC861_ASUS,
56bb0cab 153 ALC861_ASUS_LAPTOP,
df694daa
KY
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
156};
157
f32610ed
JS
158/* ALC861-VD models */
159enum {
160 ALC660VD_3ST,
6963f84c 161 ALC660VD_3ST_DIG,
13c94744 162 ALC660VD_ASUS_V1S,
f32610ed
JS
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
bdd148a3 166 ALC861VD_LENOVO,
272a527c 167 ALC861VD_DALLAS,
d1a991a6 168 ALC861VD_HP,
f32610ed
JS
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
171};
172
bc9f98a9
KY
173/* ALC662 models */
174enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
291702f0 180 ALC662_ASUS_EEEPC_P701,
8c427226 181 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
f1d4e28b
KY
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
ebb83eeb
KY
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
622e84cd
KY
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
9541ba1d 197 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
200};
201
df694daa
KY
202/* ALC882 models */
203enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
4b146cb0 206 ALC882_ARIMA,
bdd148a3 207 ALC882_W2JC,
272a527c
KY
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
914759b7 210 ALC882_ASUS_A7M,
9102cd1c 211 ALC885_MACPRO,
76e6f5a9 212 ALC885_MBA21,
87350ad0 213 ALC885_MBP3,
41d5545d 214 ALC885_MB5,
e458b1fa 215 ALC885_MACMINI3,
c54728d8 216 ALC885_IMAC24,
4b7e1803 217 ALC885_IMAC91,
9c7f852e
TI
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
ccc656ce
KY
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
64a8be74 224 ALC883_TARGA_8ch_DIG,
bab282b9 225 ALC883_ACER,
2880a867 226 ALC883_ACER_ASPIRE,
5b2d1eca 227 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 228 ALC888_ACER_ASPIRE_6530G,
3b315d70 229 ALC888_ACER_ASPIRE_8930G,
fc86f954 230 ALC888_ACER_ASPIRE_7730G,
c07584c8 231 ALC883_MEDION,
ea1fb29a 232 ALC883_MEDION_MD2,
b373bdeb 233 ALC883_LAPTOP_EAPD,
bc9f98a9 234 ALC883_LENOVO_101E_2ch,
272a527c 235 ALC883_LENOVO_NB0763,
189609ae 236 ALC888_LENOVO_MS7195_DIG,
e2757d5e 237 ALC888_LENOVO_SKY,
ea1fb29a 238 ALC883_HAIER_W66,
4723c022 239 ALC888_3ST_HP,
5795b9e6 240 ALC888_6ST_DELL,
a8848bd6 241 ALC883_MITAC,
a65cc60f 242 ALC883_CLEVO_M540R,
0c4cc443 243 ALC883_CLEVO_M720,
fb97dc67 244 ALC883_FUJITSU_PI2515,
ef8ef5fb 245 ALC888_FUJITSU_XA3530,
17bba1b7 246 ALC883_3ST_6ch_INTEL,
87a8c370
JK
247 ALC889A_INTEL,
248 ALC889_INTEL,
e2757d5e
KY
249 ALC888_ASUS_M90V,
250 ALC888_ASUS_EEE1601,
eb4c41d3 251 ALC889A_MB31,
3ab90935 252 ALC1200_ASUS_P5Q,
3e1647c5 253 ALC883_SONY_VAIO_TT,
4953550a
TI
254 ALC882_AUTO,
255 ALC882_MODEL_LAST,
9c7f852e
TI
256};
257
df694daa
KY
258/* for GPIO Poll */
259#define GPIO_MASK 0x03
260
4a79ba34
TI
261/* extra amp-initialization sequence types */
262enum {
263 ALC_INIT_NONE,
264 ALC_INIT_DEFAULT,
265 ALC_INIT_GPIO1,
266 ALC_INIT_GPIO2,
267 ALC_INIT_GPIO3,
268};
269
6c819492
TI
270struct alc_mic_route {
271 hda_nid_t pin;
272 unsigned char mux_idx;
273 unsigned char amix_idx;
274};
275
276#define MUX_IDX_UNDEF ((unsigned char)-1)
277
1da177e4
LT
278struct alc_spec {
279 /* codec parameterization */
df694daa 280 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 281 unsigned int num_mixers;
f9e336f6 282 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 283 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 284
2d9c6482 285 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
286 * don't forget NULL
287 * termination!
e9edcee0
TI
288 */
289 unsigned int num_init_verbs;
1da177e4 290
aa563af7 291 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
292 struct hda_pcm_stream *stream_analog_playback;
293 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
294 struct hda_pcm_stream *stream_analog_alt_playback;
295 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 296
aa563af7 297 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
298 struct hda_pcm_stream *stream_digital_playback;
299 struct hda_pcm_stream *stream_digital_capture;
300
301 /* playback */
16ded525
TI
302 struct hda_multi_out multiout; /* playback set-up
303 * max_channels, dacs must be set
304 * dig_out_nid and hp_nid are optional
305 */
6330079f 306 hda_nid_t alt_dac_nid;
6a05ac4a 307 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 308 int dig_out_type;
1da177e4
LT
309
310 /* capture */
311 unsigned int num_adc_nids;
312 hda_nid_t *adc_nids;
e1406348 313 hda_nid_t *capsrc_nids;
16ded525 314 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
315
316 /* capture source */
a1e8d2da 317 unsigned int num_mux_defs;
1da177e4
LT
318 const struct hda_input_mux *input_mux;
319 unsigned int cur_mux[3];
6c819492
TI
320 struct alc_mic_route ext_mic;
321 struct alc_mic_route int_mic;
1da177e4
LT
322
323 /* channel model */
d2a6d7dc 324 const struct hda_channel_mode *channel_mode;
1da177e4 325 int num_channel_mode;
4e195a7b 326 int need_dac_fix;
3b315d70
HM
327 int const_channel_count;
328 int ext_channel_count;
1da177e4
LT
329
330 /* PCM information */
4c5186ed 331 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 332
e9edcee0
TI
333 /* dynamic controls, init_verbs and input_mux */
334 struct auto_pin_cfg autocfg;
603c4019 335 struct snd_array kctls;
61b9b9b1 336 struct hda_input_mux private_imux[3];
41923e44 337 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
338 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
339 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 340
ae6b813a
TI
341 /* hooks */
342 void (*init_hook)(struct hda_codec *codec);
343 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 344#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 345 void (*power_hook)(struct hda_codec *codec);
f5de24b0 346#endif
ae6b813a 347
834be88d
TI
348 /* for pin sensing */
349 unsigned int sense_updated: 1;
350 unsigned int jack_present: 1;
bec15c3a 351 unsigned int master_sw: 1;
6c819492 352 unsigned int auto_mic:1;
cb53c626 353
e64f14f4
TI
354 /* other flags */
355 unsigned int no_analog :1; /* digital I/O only */
4a79ba34 356 int init_amp;
e64f14f4 357
2134ea4f
TI
358 /* for virtual master */
359 hda_nid_t vmaster_nid;
cb53c626
TI
360#ifdef CONFIG_SND_HDA_POWER_SAVE
361 struct hda_loopback_check loopback;
362#endif
2c3bf9ab
TI
363
364 /* for PLL fix */
365 hda_nid_t pll_nid;
366 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
367};
368
369/*
370 * configuration template - to be copied to the spec instance
371 */
372struct alc_config_preset {
9c7f852e
TI
373 struct snd_kcontrol_new *mixers[5]; /* should be identical size
374 * with spec
375 */
f9e336f6 376 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
377 const struct hda_verb *init_verbs[5];
378 unsigned int num_dacs;
379 hda_nid_t *dac_nids;
380 hda_nid_t dig_out_nid; /* optional */
381 hda_nid_t hp_nid; /* optional */
b25c9da1 382 hda_nid_t *slave_dig_outs;
df694daa
KY
383 unsigned int num_adc_nids;
384 hda_nid_t *adc_nids;
e1406348 385 hda_nid_t *capsrc_nids;
df694daa
KY
386 hda_nid_t dig_in_nid;
387 unsigned int num_channel_mode;
388 const struct hda_channel_mode *channel_mode;
4e195a7b 389 int need_dac_fix;
3b315d70 390 int const_channel_count;
a1e8d2da 391 unsigned int num_mux_defs;
df694daa 392 const struct hda_input_mux *input_mux;
ae6b813a 393 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 394 void (*setup)(struct hda_codec *);
ae6b813a 395 void (*init_hook)(struct hda_codec *);
cb53c626
TI
396#ifdef CONFIG_SND_HDA_POWER_SAVE
397 struct hda_amp_list *loopbacks;
c97259df 398 void (*power_hook)(struct hda_codec *codec);
cb53c626 399#endif
1da177e4
LT
400};
401
1da177e4
LT
402
403/*
404 * input MUX handling
405 */
9c7f852e
TI
406static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
407 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
408{
409 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
410 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
411 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
412 if (mux_idx >= spec->num_mux_defs)
413 mux_idx = 0;
414 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
415}
416
9c7f852e
TI
417static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
419{
420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421 struct alc_spec *spec = codec->spec;
422 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
423
424 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
425 return 0;
426}
427
9c7f852e
TI
428static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
429 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
430{
431 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
432 struct alc_spec *spec = codec->spec;
cd896c33 433 const struct hda_input_mux *imux;
1da177e4 434 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 435 unsigned int mux_idx;
e1406348
TI
436 hda_nid_t nid = spec->capsrc_nids ?
437 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 438 unsigned int type;
1da177e4 439
cd896c33
TI
440 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
441 imux = &spec->input_mux[mux_idx];
442
a22d543a 443 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 444 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
445 /* Matrix-mixer style (e.g. ALC882) */
446 unsigned int *cur_val = &spec->cur_mux[adc_idx];
447 unsigned int i, idx;
448
449 idx = ucontrol->value.enumerated.item[0];
450 if (idx >= imux->num_items)
451 idx = imux->num_items - 1;
452 if (*cur_val == idx)
453 return 0;
454 for (i = 0; i < imux->num_items; i++) {
455 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
456 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
457 imux->items[i].index,
458 HDA_AMP_MUTE, v);
459 }
460 *cur_val = idx;
461 return 1;
462 } else {
463 /* MUX style (e.g. ALC880) */
cd896c33 464 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
465 &spec->cur_mux[adc_idx]);
466 }
467}
e9edcee0 468
1da177e4
LT
469/*
470 * channel mode setting
471 */
9c7f852e
TI
472static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
474{
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
477 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
478 spec->num_channel_mode);
1da177e4
LT
479}
480
9c7f852e
TI
481static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
483{
484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
485 struct alc_spec *spec = codec->spec;
d2a6d7dc 486 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 487 spec->num_channel_mode,
3b315d70 488 spec->ext_channel_count);
1da177e4
LT
489}
490
9c7f852e
TI
491static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
493{
494 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
495 struct alc_spec *spec = codec->spec;
4e195a7b
TI
496 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
497 spec->num_channel_mode,
3b315d70
HM
498 &spec->ext_channel_count);
499 if (err >= 0 && !spec->const_channel_count) {
500 spec->multiout.max_channels = spec->ext_channel_count;
501 if (spec->need_dac_fix)
502 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
503 }
4e195a7b 504 return err;
1da177e4
LT
505}
506
a9430dd8 507/*
4c5186ed 508 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 509 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
510 * being part of a format specifier. Maximum allowed length of a value is
511 * 63 characters plus NULL terminator.
7cf51e48
JW
512 *
513 * Note: some retasking pin complexes seem to ignore requests for input
514 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
515 * are requested. Therefore order this list so that this behaviour will not
516 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
517 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
518 * March 2006.
4c5186ed
JW
519 */
520static char *alc_pin_mode_names[] = {
7cf51e48
JW
521 "Mic 50pc bias", "Mic 80pc bias",
522 "Line in", "Line out", "Headphone out",
4c5186ed
JW
523};
524static unsigned char alc_pin_mode_values[] = {
7cf51e48 525 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
526};
527/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
528 * in the pin being assumed to be exclusively an input or an output pin. In
529 * addition, "input" pins may or may not process the mic bias option
530 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
531 * accept requests for bias as of chip versions up to March 2006) and/or
532 * wiring in the computer.
a9430dd8 533 */
a1e8d2da
JW
534#define ALC_PIN_DIR_IN 0x00
535#define ALC_PIN_DIR_OUT 0x01
536#define ALC_PIN_DIR_INOUT 0x02
537#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
538#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 539
ea1fb29a 540/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
541 * For each direction the minimum and maximum values are given.
542 */
a1e8d2da 543static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
544 { 0, 2 }, /* ALC_PIN_DIR_IN */
545 { 3, 4 }, /* ALC_PIN_DIR_OUT */
546 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
547 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
548 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
549};
550#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
551#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
552#define alc_pin_mode_n_items(_dir) \
553 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
554
9c7f852e
TI
555static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
556 struct snd_ctl_elem_info *uinfo)
a9430dd8 557{
4c5186ed
JW
558 unsigned int item_num = uinfo->value.enumerated.item;
559 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
560
561 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 562 uinfo->count = 1;
4c5186ed
JW
563 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
564
565 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
566 item_num = alc_pin_mode_min(dir);
567 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
568 return 0;
569}
570
9c7f852e
TI
571static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
572 struct snd_ctl_elem_value *ucontrol)
a9430dd8 573{
4c5186ed 574 unsigned int i;
a9430dd8
JW
575 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
576 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 577 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 578 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
579 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
580 AC_VERB_GET_PIN_WIDGET_CONTROL,
581 0x00);
a9430dd8 582
4c5186ed
JW
583 /* Find enumerated value for current pinctl setting */
584 i = alc_pin_mode_min(dir);
4b35d2ca 585 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 586 i++;
9c7f852e 587 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
588 return 0;
589}
590
9c7f852e
TI
591static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
a9430dd8 593{
4c5186ed 594 signed int change;
a9430dd8
JW
595 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
596 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
597 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
598 long val = *ucontrol->value.integer.value;
9c7f852e
TI
599 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
600 AC_VERB_GET_PIN_WIDGET_CONTROL,
601 0x00);
a9430dd8 602
f12ab1e0 603 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
604 val = alc_pin_mode_min(dir);
605
606 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
607 if (change) {
608 /* Set pin mode to that requested */
82beb8fd
TI
609 snd_hda_codec_write_cache(codec, nid, 0,
610 AC_VERB_SET_PIN_WIDGET_CONTROL,
611 alc_pin_mode_values[val]);
cdcd9268 612
ea1fb29a 613 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
614 * for the requested pin mode. Enum values of 2 or less are
615 * input modes.
616 *
617 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
618 * reduces noise slightly (particularly on input) so we'll
619 * do it. However, having both input and output buffers
620 * enabled simultaneously doesn't seem to be problematic if
621 * this turns out to be necessary in the future.
cdcd9268
JW
622 */
623 if (val <= 2) {
47fd830a
TI
624 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
625 HDA_AMP_MUTE, HDA_AMP_MUTE);
626 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
627 HDA_AMP_MUTE, 0);
cdcd9268 628 } else {
47fd830a
TI
629 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
630 HDA_AMP_MUTE, HDA_AMP_MUTE);
631 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
632 HDA_AMP_MUTE, 0);
cdcd9268
JW
633 }
634 }
a9430dd8
JW
635 return change;
636}
637
4c5186ed 638#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 639 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 640 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
641 .info = alc_pin_mode_info, \
642 .get = alc_pin_mode_get, \
643 .put = alc_pin_mode_put, \
644 .private_value = nid | (dir<<16) }
df694daa 645
5c8f858d
JW
646/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
647 * together using a mask with more than one bit set. This control is
648 * currently used only by the ALC260 test model. At this stage they are not
649 * needed for any "production" models.
650 */
651#ifdef CONFIG_SND_DEBUG
a5ce8890 652#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 653
9c7f852e
TI
654static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
656{
657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
658 hda_nid_t nid = kcontrol->private_value & 0xffff;
659 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
660 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
661 unsigned int val = snd_hda_codec_read(codec, nid, 0,
662 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
663
664 *valp = (val & mask) != 0;
665 return 0;
666}
9c7f852e
TI
667static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
668 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
669{
670 signed int change;
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672 hda_nid_t nid = kcontrol->private_value & 0xffff;
673 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
674 long val = *ucontrol->value.integer.value;
9c7f852e
TI
675 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
676 AC_VERB_GET_GPIO_DATA,
677 0x00);
5c8f858d
JW
678
679 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
680 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
681 if (val == 0)
5c8f858d
JW
682 gpio_data &= ~mask;
683 else
684 gpio_data |= mask;
82beb8fd
TI
685 snd_hda_codec_write_cache(codec, nid, 0,
686 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
687
688 return change;
689}
690#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
691 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 692 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
693 .info = alc_gpio_data_info, \
694 .get = alc_gpio_data_get, \
695 .put = alc_gpio_data_put, \
696 .private_value = nid | (mask<<16) }
697#endif /* CONFIG_SND_DEBUG */
698
92621f13
JW
699/* A switch control to allow the enabling of the digital IO pins on the
700 * ALC260. This is incredibly simplistic; the intention of this control is
701 * to provide something in the test model allowing digital outputs to be
702 * identified if present. If models are found which can utilise these
703 * outputs a more complete mixer control can be devised for those models if
704 * necessary.
705 */
706#ifdef CONFIG_SND_DEBUG
a5ce8890 707#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 708
9c7f852e
TI
709static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
710 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
711{
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 *valp = ucontrol->value.integer.value;
9c7f852e 716 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 717 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
718
719 *valp = (val & mask) != 0;
720 return 0;
721}
9c7f852e
TI
722static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
723 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
724{
725 signed int change;
726 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
727 hda_nid_t nid = kcontrol->private_value & 0xffff;
728 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
729 long val = *ucontrol->value.integer.value;
9c7f852e 730 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 731 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 732 0x00);
92621f13
JW
733
734 /* Set/unset the masked control bit(s) as needed */
9c7f852e 735 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
736 if (val==0)
737 ctrl_data &= ~mask;
738 else
739 ctrl_data |= mask;
82beb8fd
TI
740 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
741 ctrl_data);
92621f13
JW
742
743 return change;
744}
745#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
746 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 747 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
748 .info = alc_spdif_ctrl_info, \
749 .get = alc_spdif_ctrl_get, \
750 .put = alc_spdif_ctrl_put, \
751 .private_value = nid | (mask<<16) }
752#endif /* CONFIG_SND_DEBUG */
753
f8225f6d
JW
754/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
755 * Again, this is only used in the ALC26x test models to help identify when
756 * the EAPD line must be asserted for features to work.
757 */
758#ifdef CONFIG_SND_DEBUG
759#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
760
761static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
762 struct snd_ctl_elem_value *ucontrol)
763{
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 *valp = ucontrol->value.integer.value;
768 unsigned int val = snd_hda_codec_read(codec, nid, 0,
769 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
770
771 *valp = (val & mask) != 0;
772 return 0;
773}
774
775static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
776 struct snd_ctl_elem_value *ucontrol)
777{
778 int change;
779 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
780 hda_nid_t nid = kcontrol->private_value & 0xffff;
781 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
782 long val = *ucontrol->value.integer.value;
783 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
784 AC_VERB_GET_EAPD_BTLENABLE,
785 0x00);
786
787 /* Set/unset the masked control bit(s) as needed */
788 change = (!val ? 0 : mask) != (ctrl_data & mask);
789 if (!val)
790 ctrl_data &= ~mask;
791 else
792 ctrl_data |= mask;
793 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
794 ctrl_data);
795
796 return change;
797}
798
799#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
800 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 801 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
802 .info = alc_eapd_ctrl_info, \
803 .get = alc_eapd_ctrl_get, \
804 .put = alc_eapd_ctrl_put, \
805 .private_value = nid | (mask<<16) }
806#endif /* CONFIG_SND_DEBUG */
807
23f0c048
TI
808/*
809 * set up the input pin config (depending on the given auto-pin type)
810 */
811static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
812 int auto_pin_type)
813{
814 unsigned int val = PIN_IN;
815
816 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
817 unsigned int pincap;
1327a32b 818 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
819 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
820 if (pincap & AC_PINCAP_VREF_80)
821 val = PIN_VREF80;
461c6c3a
TI
822 else if (pincap & AC_PINCAP_VREF_50)
823 val = PIN_VREF50;
824 else if (pincap & AC_PINCAP_VREF_100)
825 val = PIN_VREF100;
826 else if (pincap & AC_PINCAP_VREF_GRD)
827 val = PIN_VREFGRD;
23f0c048
TI
828 }
829 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
830}
831
d88897ea
TI
832/*
833 */
834static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
835{
836 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
837 return;
838 spec->mixers[spec->num_mixers++] = mix;
839}
840
841static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
842{
843 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
844 return;
845 spec->init_verbs[spec->num_init_verbs++] = verb;
846}
847
df694daa
KY
848/*
849 * set up from the preset table
850 */
e9c364c0 851static void setup_preset(struct hda_codec *codec,
9c7f852e 852 const struct alc_config_preset *preset)
df694daa 853{
e9c364c0 854 struct alc_spec *spec = codec->spec;
df694daa
KY
855 int i;
856
857 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 858 add_mixer(spec, preset->mixers[i]);
f9e336f6 859 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
860 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
861 i++)
d88897ea 862 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 863
df694daa
KY
864 spec->channel_mode = preset->channel_mode;
865 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 866 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 867 spec->const_channel_count = preset->const_channel_count;
df694daa 868
3b315d70
HM
869 if (preset->const_channel_count)
870 spec->multiout.max_channels = preset->const_channel_count;
871 else
872 spec->multiout.max_channels = spec->channel_mode[0].channels;
873 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
874
875 spec->multiout.num_dacs = preset->num_dacs;
876 spec->multiout.dac_nids = preset->dac_nids;
877 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 878 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 879 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 880
a1e8d2da 881 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 882 if (!spec->num_mux_defs)
a1e8d2da 883 spec->num_mux_defs = 1;
df694daa
KY
884 spec->input_mux = preset->input_mux;
885
886 spec->num_adc_nids = preset->num_adc_nids;
887 spec->adc_nids = preset->adc_nids;
e1406348 888 spec->capsrc_nids = preset->capsrc_nids;
df694daa 889 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
890
891 spec->unsol_event = preset->unsol_event;
892 spec->init_hook = preset->init_hook;
cb53c626 893#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 894 spec->power_hook = preset->power_hook;
cb53c626
TI
895 spec->loopback.amplist = preset->loopbacks;
896#endif
e9c364c0
TI
897
898 if (preset->setup)
899 preset->setup(codec);
df694daa
KY
900}
901
bc9f98a9
KY
902/* Enable GPIO mask and set output */
903static struct hda_verb alc_gpio1_init_verbs[] = {
904 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
905 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
906 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
907 { }
908};
909
910static struct hda_verb alc_gpio2_init_verbs[] = {
911 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
912 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
913 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
914 { }
915};
916
bdd148a3
KY
917static struct hda_verb alc_gpio3_init_verbs[] = {
918 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
919 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
920 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
921 { }
922};
923
2c3bf9ab
TI
924/*
925 * Fix hardware PLL issue
926 * On some codecs, the analog PLL gating control must be off while
927 * the default value is 1.
928 */
929static void alc_fix_pll(struct hda_codec *codec)
930{
931 struct alc_spec *spec = codec->spec;
932 unsigned int val;
933
934 if (!spec->pll_nid)
935 return;
936 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
937 spec->pll_coef_idx);
938 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
939 AC_VERB_GET_PROC_COEF, 0);
940 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
941 spec->pll_coef_idx);
942 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
943 val & ~(1 << spec->pll_coef_bit));
944}
945
946static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
947 unsigned int coef_idx, unsigned int coef_bit)
948{
949 struct alc_spec *spec = codec->spec;
950 spec->pll_nid = nid;
951 spec->pll_coef_idx = coef_idx;
952 spec->pll_coef_bit = coef_bit;
953 alc_fix_pll(codec);
954}
955
a9fd4f3f 956static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
957{
958 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
959 unsigned int nid = spec->autocfg.hp_pins[0];
960 int i;
c9b58006 961
ad87c64f
TI
962 if (!nid)
963 return;
864f92be 964 spec->jack_present = snd_hda_jack_detect(codec, nid);
a9fd4f3f
TI
965 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
966 nid = spec->autocfg.speaker_pins[i];
967 if (!nid)
968 break;
969 snd_hda_codec_write(codec, nid, 0,
970 AC_VERB_SET_PIN_WIDGET_CONTROL,
971 spec->jack_present ? 0 : PIN_OUT);
972 }
c9b58006
KY
973}
974
6c819492
TI
975static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
976 hda_nid_t nid)
977{
978 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
979 int i, nums;
980
981 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
982 for (i = 0; i < nums; i++)
983 if (conn[i] == nid)
984 return i;
985 return -1;
986}
987
7fb0d78f
KY
988static void alc_mic_automute(struct hda_codec *codec)
989{
990 struct alc_spec *spec = codec->spec;
6c819492
TI
991 struct alc_mic_route *dead, *alive;
992 unsigned int present, type;
993 hda_nid_t cap_nid;
994
b59bdf3b
TI
995 if (!spec->auto_mic)
996 return;
6c819492
TI
997 if (!spec->int_mic.pin || !spec->ext_mic.pin)
998 return;
999 if (snd_BUG_ON(!spec->adc_nids))
1000 return;
1001
1002 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1003
864f92be 1004 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1005 if (present) {
1006 alive = &spec->ext_mic;
1007 dead = &spec->int_mic;
1008 } else {
1009 alive = &spec->int_mic;
1010 dead = &spec->ext_mic;
1011 }
1012
6c819492
TI
1013 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1014 if (type == AC_WID_AUD_MIX) {
1015 /* Matrix-mixer style (e.g. ALC882) */
1016 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1017 alive->mux_idx,
1018 HDA_AMP_MUTE, 0);
1019 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1020 dead->mux_idx,
1021 HDA_AMP_MUTE, HDA_AMP_MUTE);
1022 } else {
1023 /* MUX style (e.g. ALC880) */
1024 snd_hda_codec_write_cache(codec, cap_nid, 0,
1025 AC_VERB_SET_CONNECT_SEL,
1026 alive->mux_idx);
1027 }
1028
1029 /* FIXME: analog mixer */
7fb0d78f
KY
1030}
1031
c9b58006
KY
1032/* unsolicited event for HP jack sensing */
1033static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1034{
1035 if (codec->vendor_id == 0x10ec0880)
1036 res >>= 28;
1037 else
1038 res >>= 26;
a9fd4f3f
TI
1039 switch (res) {
1040 case ALC880_HP_EVENT:
1041 alc_automute_pin(codec);
1042 break;
1043 case ALC880_MIC_EVENT:
7fb0d78f 1044 alc_mic_automute(codec);
a9fd4f3f
TI
1045 break;
1046 }
7fb0d78f
KY
1047}
1048
1049static void alc_inithook(struct hda_codec *codec)
1050{
a9fd4f3f 1051 alc_automute_pin(codec);
7fb0d78f 1052 alc_mic_automute(codec);
c9b58006
KY
1053}
1054
f9423e7a
KY
1055/* additional initialization for ALC888 variants */
1056static void alc888_coef_init(struct hda_codec *codec)
1057{
1058 unsigned int tmp;
1059
1060 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1061 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1062 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1063 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1064 /* alc888S-VC */
1065 snd_hda_codec_read(codec, 0x20, 0,
1066 AC_VERB_SET_PROC_COEF, 0x830);
1067 else
1068 /* alc888-VB */
1069 snd_hda_codec_read(codec, 0x20, 0,
1070 AC_VERB_SET_PROC_COEF, 0x3030);
1071}
1072
87a8c370
JK
1073static void alc889_coef_init(struct hda_codec *codec)
1074{
1075 unsigned int tmp;
1076
1077 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1078 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1079 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1080 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1081}
1082
3fb4a508
TI
1083/* turn on/off EAPD control (only if available) */
1084static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1085{
1086 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1087 return;
1088 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1089 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1090 on ? 2 : 0);
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 1109 case 0x10ec0260:
3fb4a508
TI
1110 set_eapd(codec, 0x0f, 1);
1111 set_eapd(codec, 0x10, 1);
c9b58006
KY
1112 break;
1113 case 0x10ec0262:
bdd148a3
KY
1114 case 0x10ec0267:
1115 case 0x10ec0268:
c9b58006 1116 case 0x10ec0269:
3fb4a508 1117 case 0x10ec0270:
c6e8f2da 1118 case 0x10ec0272:
f9423e7a
KY
1119 case 0x10ec0660:
1120 case 0x10ec0662:
1121 case 0x10ec0663:
c9b58006 1122 case 0x10ec0862:
20a3a05d 1123 case 0x10ec0889:
3fb4a508
TI
1124 set_eapd(codec, 0x14, 1);
1125 set_eapd(codec, 0x15, 1);
c9b58006 1126 break;
bdd148a3 1127 }
c9b58006
KY
1128 switch (codec->vendor_id) {
1129 case 0x10ec0260:
1130 snd_hda_codec_write(codec, 0x1a, 0,
1131 AC_VERB_SET_COEF_INDEX, 7);
1132 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1133 AC_VERB_GET_PROC_COEF, 0);
1134 snd_hda_codec_write(codec, 0x1a, 0,
1135 AC_VERB_SET_COEF_INDEX, 7);
1136 snd_hda_codec_write(codec, 0x1a, 0,
1137 AC_VERB_SET_PROC_COEF,
1138 tmp | 0x2010);
1139 break;
1140 case 0x10ec0262:
1141 case 0x10ec0880:
1142 case 0x10ec0882:
1143 case 0x10ec0883:
1144 case 0x10ec0885:
4a5a4c56 1145 case 0x10ec0887:
20a3a05d 1146 case 0x10ec0889:
87a8c370 1147 alc889_coef_init(codec);
c9b58006 1148 break;
f9423e7a 1149 case 0x10ec0888:
4a79ba34 1150 alc888_coef_init(codec);
f9423e7a 1151 break;
0aea778e 1152#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1153 case 0x10ec0267:
1154 case 0x10ec0268:
1155 snd_hda_codec_write(codec, 0x20, 0,
1156 AC_VERB_SET_COEF_INDEX, 7);
1157 tmp = snd_hda_codec_read(codec, 0x20, 0,
1158 AC_VERB_GET_PROC_COEF, 0);
1159 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1160 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1161 snd_hda_codec_write(codec, 0x20, 0,
1162 AC_VERB_SET_PROC_COEF,
1163 tmp | 0x3000);
1164 break;
0aea778e 1165#endif /* XXX */
bc9f98a9 1166 }
4a79ba34
TI
1167 break;
1168 }
1169}
1170
1171static void alc_init_auto_hp(struct hda_codec *codec)
1172{
1173 struct alc_spec *spec = codec->spec;
1174
1175 if (!spec->autocfg.hp_pins[0])
1176 return;
1177
1178 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1179 if (spec->autocfg.line_out_pins[0] &&
1180 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1181 spec->autocfg.speaker_pins[0] =
1182 spec->autocfg.line_out_pins[0];
1183 else
1184 return;
1185 }
1186
2a2ed0df
TI
1187 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1188 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1189 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1190 AC_VERB_SET_UNSOLICITED_ENABLE,
1191 AC_USRSP_EN | ALC880_HP_EVENT);
1192 spec->unsol_event = alc_sku_unsol_event;
1193}
1194
6c819492
TI
1195static void alc_init_auto_mic(struct hda_codec *codec)
1196{
1197 struct alc_spec *spec = codec->spec;
1198 struct auto_pin_cfg *cfg = &spec->autocfg;
1199 hda_nid_t fixed, ext;
1200 int i;
1201
1202 /* there must be only two mic inputs exclusively */
1203 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1204 if (cfg->input_pins[i])
1205 return;
1206
1207 fixed = ext = 0;
1208 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1209 hda_nid_t nid = cfg->input_pins[i];
1210 unsigned int defcfg;
1211 if (!nid)
1212 return;
1213 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1214 switch (get_defcfg_connect(defcfg)) {
1215 case AC_JACK_PORT_FIXED:
1216 if (fixed)
1217 return; /* already occupied */
1218 fixed = nid;
1219 break;
1220 case AC_JACK_PORT_COMPLEX:
1221 if (ext)
1222 return; /* already occupied */
1223 ext = nid;
1224 break;
1225 default:
1226 return; /* invalid entry */
1227 }
1228 }
eaa9b3a7
TI
1229 if (!ext || !fixed)
1230 return;
6c819492
TI
1231 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1232 return; /* no unsol support */
1233 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1234 ext, fixed);
1235 spec->ext_mic.pin = ext;
1236 spec->int_mic.pin = fixed;
1237 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1238 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1239 spec->auto_mic = 1;
1240 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1241 AC_VERB_SET_UNSOLICITED_ENABLE,
1242 AC_USRSP_EN | ALC880_MIC_EVENT);
1243 spec->unsol_event = alc_sku_unsol_event;
1244}
1245
4a79ba34
TI
1246/* check subsystem ID and set up device-specific initialization;
1247 * return 1 if initialized, 0 if invalid SSID
1248 */
1249/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1250 * 31 ~ 16 : Manufacture ID
1251 * 15 ~ 8 : SKU ID
1252 * 7 ~ 0 : Assembly ID
1253 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1254 */
1255static int alc_subsystem_id(struct hda_codec *codec,
1256 hda_nid_t porta, hda_nid_t porte,
6227cdce 1257 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1258{
1259 unsigned int ass, tmp, i;
1260 unsigned nid;
1261 struct alc_spec *spec = codec->spec;
1262
1263 ass = codec->subsystem_id & 0xffff;
1264 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1265 goto do_sku;
1266
1267 /* invalid SSID, check the special NID pin defcfg instead */
1268 /*
def319f9 1269 * 31~30 : port connectivity
4a79ba34
TI
1270 * 29~21 : reserve
1271 * 20 : PCBEEP input
1272 * 19~16 : Check sum (15:1)
1273 * 15~1 : Custom
1274 * 0 : override
1275 */
1276 nid = 0x1d;
1277 if (codec->vendor_id == 0x10ec0260)
1278 nid = 0x17;
1279 ass = snd_hda_codec_get_pincfg(codec, nid);
1280 snd_printd("realtek: No valid SSID, "
1281 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1282 ass, nid);
6227cdce 1283 if (!(ass & 1))
4a79ba34
TI
1284 return 0;
1285 if ((ass >> 30) != 1) /* no physical connection */
1286 return 0;
1287
1288 /* check sum */
1289 tmp = 0;
1290 for (i = 1; i < 16; i++) {
1291 if ((ass >> i) & 1)
1292 tmp++;
1293 }
1294 if (((ass >> 16) & 0xf) != tmp)
1295 return 0;
1296do_sku:
1297 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1298 ass & 0xffff, codec->vendor_id);
1299 /*
1300 * 0 : override
1301 * 1 : Swap Jack
1302 * 2 : 0 --> Desktop, 1 --> Laptop
1303 * 3~5 : External Amplifier control
1304 * 7~6 : Reserved
1305 */
1306 tmp = (ass & 0x38) >> 3; /* external Amp control */
1307 switch (tmp) {
1308 case 1:
1309 spec->init_amp = ALC_INIT_GPIO1;
1310 break;
1311 case 3:
1312 spec->init_amp = ALC_INIT_GPIO2;
1313 break;
1314 case 7:
1315 spec->init_amp = ALC_INIT_GPIO3;
1316 break;
1317 case 5:
1318 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1319 break;
1320 }
ea1fb29a 1321
8c427226 1322 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1323 * when the external headphone out jack is plugged"
1324 */
8c427226 1325 if (!(ass & 0x8000))
4a79ba34 1326 return 1;
c9b58006
KY
1327 /*
1328 * 10~8 : Jack location
1329 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1330 * 14~13: Resvered
1331 * 15 : 1 --> enable the function "Mute internal speaker
1332 * when the external headphone out jack is plugged"
1333 */
c9b58006 1334 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1335 hda_nid_t nid;
c9b58006
KY
1336 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1337 if (tmp == 0)
01d4825d 1338 nid = porta;
c9b58006 1339 else if (tmp == 1)
01d4825d 1340 nid = porte;
c9b58006 1341 else if (tmp == 2)
01d4825d 1342 nid = portd;
6227cdce
KY
1343 else if (tmp == 3)
1344 nid = porti;
c9b58006 1345 else
4a79ba34 1346 return 1;
01d4825d
TI
1347 for (i = 0; i < spec->autocfg.line_outs; i++)
1348 if (spec->autocfg.line_out_pins[i] == nid)
1349 return 1;
1350 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1351 }
1352
4a79ba34 1353 alc_init_auto_hp(codec);
6c819492 1354 alc_init_auto_mic(codec);
4a79ba34
TI
1355 return 1;
1356}
ea1fb29a 1357
4a79ba34 1358static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1359 hda_nid_t porta, hda_nid_t porte,
1360 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1361{
6227cdce 1362 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1363 struct alc_spec *spec = codec->spec;
1364 snd_printd("realtek: "
1365 "Enable default setup for auto mode as fallback\n");
1366 spec->init_amp = ALC_INIT_DEFAULT;
1367 alc_init_auto_hp(codec);
6c819492 1368 alc_init_auto_mic(codec);
4a79ba34 1369 }
bc9f98a9
KY
1370}
1371
f95474ec 1372/*
f8f25ba3 1373 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1374 */
1375
1376struct alc_pincfg {
1377 hda_nid_t nid;
1378 u32 val;
1379};
1380
f8f25ba3
TI
1381struct alc_fixup {
1382 const struct alc_pincfg *pins;
1383 const struct hda_verb *verbs;
1384};
1385
1386static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1387 const struct snd_pci_quirk *quirk,
f8f25ba3 1388 const struct alc_fixup *fix)
f95474ec
TI
1389{
1390 const struct alc_pincfg *cfg;
1391
1392 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1393 if (!quirk)
1394 return;
1395
f8f25ba3
TI
1396 fix += quirk->value;
1397 cfg = fix->pins;
1398 if (cfg) {
1399 for (; cfg->nid; cfg++)
1400 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1401 }
1402 if (fix->verbs)
1403 add_verb(codec->spec, fix->verbs);
f95474ec
TI
1404}
1405
274693f3
KY
1406static int alc_read_coef_idx(struct hda_codec *codec,
1407 unsigned int coef_idx)
1408{
1409 unsigned int val;
1410 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1411 coef_idx);
1412 val = snd_hda_codec_read(codec, 0x20, 0,
1413 AC_VERB_GET_PROC_COEF, 0);
1414 return val;
1415}
1416
ef8ef5fb
VP
1417/*
1418 * ALC888
1419 */
1420
1421/*
1422 * 2ch mode
1423 */
1424static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1425/* Mic-in jack as mic in */
1426 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1427 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1428/* Line-in jack as Line in */
1429 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1430 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1431/* Line-Out as Front */
1432 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1433 { } /* end */
1434};
1435
1436/*
1437 * 4ch mode
1438 */
1439static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1440/* Mic-in jack as mic in */
1441 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1442 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
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 Front */
1447 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1448 { } /* end */
1449};
1450
1451/*
1452 * 6ch mode
1453 */
1454static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1455/* Mic-in jack as CLFE */
1456 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1457 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1458/* Line-in jack as Surround */
1459 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1460 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1461/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1462 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1463 { } /* end */
1464};
1465
1466/*
1467 * 8ch mode
1468 */
1469static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1470/* Mic-in jack as CLFE */
1471 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1472 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1473/* Line-in jack as Surround */
1474 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1475 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1476/* Line-Out as Side */
1477 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1478 { } /* end */
1479};
1480
1481static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1482 { 2, alc888_4ST_ch2_intel_init },
1483 { 4, alc888_4ST_ch4_intel_init },
1484 { 6, alc888_4ST_ch6_intel_init },
1485 { 8, alc888_4ST_ch8_intel_init },
1486};
1487
1488/*
1489 * ALC888 Fujitsu Siemens Amillo xa3530
1490 */
1491
1492static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1493/* Front Mic: set to PIN_IN (empty by default) */
1494 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1495/* Connect Internal HP to Front */
1496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1499/* Connect Bass HP to Front */
1500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1502 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1503/* Connect Line-Out side jack (SPDIF) to Side */
1504 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1506 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1507/* Connect Mic jack to CLFE */
1508 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1510 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1511/* Connect Line-in jack to Surround */
1512 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1514 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1515/* Connect HP out jack to Front */
1516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1518 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1519/* Enable unsolicited event for HP jack and Line-out jack */
1520 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1521 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1522 {}
1523};
1524
a9fd4f3f 1525static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1526{
a9fd4f3f 1527 struct alc_spec *spec = codec->spec;
864f92be 1528 unsigned int mute;
a9fd4f3f
TI
1529 hda_nid_t nid;
1530 int i;
1531
1532 spec->jack_present = 0;
1533 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1534 nid = spec->autocfg.hp_pins[i];
1535 if (!nid)
1536 break;
864f92be 1537 if (snd_hda_jack_detect(codec, nid)) {
a9fd4f3f
TI
1538 spec->jack_present = 1;
1539 break;
1540 }
1541 }
1542
1543 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1544 /* Toggle internal speakers muting */
a9fd4f3f
TI
1545 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1546 nid = spec->autocfg.speaker_pins[i];
1547 if (!nid)
1548 break;
1549 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1550 HDA_AMP_MUTE, mute);
1551 }
ef8ef5fb
VP
1552}
1553
a9fd4f3f
TI
1554static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1555 unsigned int res)
ef8ef5fb 1556{
a9fd4f3f
TI
1557 if (codec->vendor_id == 0x10ec0880)
1558 res >>= 28;
1559 else
1560 res >>= 26;
1561 if (res == ALC880_HP_EVENT)
1562 alc_automute_amp(codec);
ef8ef5fb
VP
1563}
1564
4f5d1706 1565static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1566{
1567 struct alc_spec *spec = codec->spec;
1568
1569 spec->autocfg.hp_pins[0] = 0x15;
1570 spec->autocfg.speaker_pins[0] = 0x14;
1571 spec->autocfg.speaker_pins[1] = 0x16;
1572 spec->autocfg.speaker_pins[2] = 0x17;
1573 spec->autocfg.speaker_pins[3] = 0x19;
1574 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1575}
1576
1577static void alc889_intel_init_hook(struct hda_codec *codec)
1578{
1579 alc889_coef_init(codec);
4f5d1706 1580 alc_automute_amp(codec);
6732bd0d
WF
1581}
1582
4f5d1706 1583static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1584{
1585 struct alc_spec *spec = codec->spec;
1586
1587 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1588 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1589 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1590 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1591}
ef8ef5fb 1592
5b2d1eca
VP
1593/*
1594 * ALC888 Acer Aspire 4930G model
1595 */
1596
1597static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
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)},
ef8ef5fb 1602/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1603 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1604/* Connect Internal HP to front */
1605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1607 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1608/* Connect HP out to front */
1609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1612 { }
1613};
1614
d2fd4b09
TV
1615/*
1616 * ALC888 Acer Aspire 6530G model
1617 */
1618
1619static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1620/* Bias voltage on for external mic port */
1621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1622/* Front Mic: set to PIN_IN (empty by default) */
1623 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1624/* Unselect Front Mic by default in input mixer 3 */
1625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1626/* Enable unsolicited event for HP jack */
1627 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1628/* Enable speaker output */
1629 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1630 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1631/* Enable headphone output */
1632 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1635 { }
1636};
1637
3b315d70 1638/*
018df418 1639 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1640 */
1641
018df418 1642static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1643/* Front Mic: set to PIN_IN (empty by default) */
1644 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1645/* Unselect Front Mic by default in input mixer 3 */
1646 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1647/* Enable unsolicited event for HP jack */
1648 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1649/* Connect Internal Front to Front */
1650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1651 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1652 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1653/* Connect Internal Rear to Rear */
1654 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1655 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1656 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1657/* Connect Internal CLFE to CLFE */
1658 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1659 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1660 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1661/* Connect HP out to Front */
018df418 1662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1664 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1665/* Enable all DACs */
1666/* DAC DISABLE/MUTE 1? */
1667/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1668 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1669 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1670/* DAC DISABLE/MUTE 2? */
1671/* some bit here disables the other DACs. Init=0x4900 */
1672 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1673 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1674/* DMIC fix
1675 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1676 * which makes the stereo useless. However, either the mic or the ALC889
1677 * makes the signal become a difference/sum signal instead of standard
1678 * stereo, which is annoying. So instead we flip this bit which makes the
1679 * codec replicate the sum signal to both channels, turning it into a
1680 * normal mono mic.
1681 */
1682/* DMIC_CONTROL? Init value = 0x0001 */
1683 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1684 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1685 { }
1686};
1687
ef8ef5fb 1688static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1689 /* Front mic only available on one ADC */
1690 {
1691 .num_items = 4,
1692 .items = {
1693 { "Mic", 0x0 },
1694 { "Line", 0x2 },
1695 { "CD", 0x4 },
1696 { "Front Mic", 0xb },
1697 },
1698 },
1699 {
1700 .num_items = 3,
1701 .items = {
1702 { "Mic", 0x0 },
1703 { "Line", 0x2 },
1704 { "CD", 0x4 },
1705 },
1706 }
1707};
1708
d2fd4b09
TV
1709static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1710 /* Interal mic only available on one ADC */
1711 {
684a8842 1712 .num_items = 5,
d2fd4b09
TV
1713 .items = {
1714 { "Ext Mic", 0x0 },
684a8842 1715 { "Line In", 0x2 },
d2fd4b09 1716 { "CD", 0x4 },
684a8842 1717 { "Input Mix", 0xa },
d2fd4b09
TV
1718 { "Int Mic", 0xb },
1719 },
1720 },
1721 {
684a8842 1722 .num_items = 4,
d2fd4b09
TV
1723 .items = {
1724 { "Ext Mic", 0x0 },
684a8842 1725 { "Line In", 0x2 },
d2fd4b09 1726 { "CD", 0x4 },
684a8842 1727 { "Input Mix", 0xa },
d2fd4b09
TV
1728 },
1729 }
1730};
1731
018df418
HM
1732static struct hda_input_mux alc889_capture_sources[3] = {
1733 /* Digital mic only available on first "ADC" */
1734 {
1735 .num_items = 5,
1736 .items = {
1737 { "Mic", 0x0 },
1738 { "Line", 0x2 },
1739 { "CD", 0x4 },
1740 { "Front Mic", 0xb },
1741 { "Input Mix", 0xa },
1742 },
1743 },
1744 {
1745 .num_items = 4,
1746 .items = {
1747 { "Mic", 0x0 },
1748 { "Line", 0x2 },
1749 { "CD", 0x4 },
1750 { "Input Mix", 0xa },
1751 },
1752 },
1753 {
1754 .num_items = 4,
1755 .items = {
1756 { "Mic", 0x0 },
1757 { "Line", 0x2 },
1758 { "CD", 0x4 },
1759 { "Input Mix", 0xa },
1760 },
1761 }
1762};
1763
ef8ef5fb 1764static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1765 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1766 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1767 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1768 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1769 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1770 HDA_OUTPUT),
1771 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1772 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1773 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1774 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1775 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1781 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1783 { } /* end */
1784};
1785
556eea9a
HM
1786static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1787 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1788 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1789 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1790 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1791 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1792 HDA_OUTPUT),
1793 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1794 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1795 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1796 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1797 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1800 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1801 { } /* end */
1802};
1803
1804
4f5d1706 1805static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 1806{
a9fd4f3f 1807 struct alc_spec *spec = codec->spec;
5b2d1eca 1808
a9fd4f3f
TI
1809 spec->autocfg.hp_pins[0] = 0x15;
1810 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
1811 spec->autocfg.speaker_pins[1] = 0x16;
1812 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
1813}
1814
4f5d1706 1815static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
1816{
1817 struct alc_spec *spec = codec->spec;
1818
1819 spec->autocfg.hp_pins[0] = 0x15;
1820 spec->autocfg.speaker_pins[0] = 0x14;
1821 spec->autocfg.speaker_pins[1] = 0x16;
1822 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
1823}
1824
4f5d1706 1825static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
1826{
1827 struct alc_spec *spec = codec->spec;
1828
1829 spec->autocfg.hp_pins[0] = 0x15;
1830 spec->autocfg.speaker_pins[0] = 0x14;
1831 spec->autocfg.speaker_pins[1] = 0x16;
1832 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
1833}
1834
1da177e4 1835/*
e9edcee0
TI
1836 * ALC880 3-stack model
1837 *
1838 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1839 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1840 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1841 */
1842
e9edcee0
TI
1843static hda_nid_t alc880_dac_nids[4] = {
1844 /* front, rear, clfe, rear_surr */
1845 0x02, 0x05, 0x04, 0x03
1846};
1847
1848static hda_nid_t alc880_adc_nids[3] = {
1849 /* ADC0-2 */
1850 0x07, 0x08, 0x09,
1851};
1852
1853/* The datasheet says the node 0x07 is connected from inputs,
1854 * but it shows zero connection in the real implementation on some devices.
df694daa 1855 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1856 */
e9edcee0
TI
1857static hda_nid_t alc880_adc_nids_alt[2] = {
1858 /* ADC1-2 */
1859 0x08, 0x09,
1860};
1861
1862#define ALC880_DIGOUT_NID 0x06
1863#define ALC880_DIGIN_NID 0x0a
1864
1865static struct hda_input_mux alc880_capture_source = {
1866 .num_items = 4,
1867 .items = {
1868 { "Mic", 0x0 },
1869 { "Front Mic", 0x3 },
1870 { "Line", 0x2 },
1871 { "CD", 0x4 },
1872 },
1873};
1874
1875/* channel source setting (2/6 channel selection for 3-stack) */
1876/* 2ch mode */
1877static struct hda_verb alc880_threestack_ch2_init[] = {
1878 /* set line-in to input, mute it */
1879 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1880 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1881 /* set mic-in to input vref 80%, mute it */
1882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1884 { } /* end */
1885};
1886
1887/* 6ch mode */
1888static struct hda_verb alc880_threestack_ch6_init[] = {
1889 /* set line-in to output, unmute it */
1890 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1891 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1892 /* set mic-in to output, unmute it */
1893 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1894 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1895 { } /* end */
1896};
1897
d2a6d7dc 1898static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1899 { 2, alc880_threestack_ch2_init },
1900 { 6, alc880_threestack_ch6_init },
1901};
1902
c8b6bf9b 1903static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1905 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1906 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1907 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1908 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1909 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1910 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1911 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1912 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1913 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1914 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1915 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1917 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1918 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1919 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1921 {
1922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1923 .name = "Channel Mode",
df694daa
KY
1924 .info = alc_ch_mode_info,
1925 .get = alc_ch_mode_get,
1926 .put = alc_ch_mode_put,
e9edcee0
TI
1927 },
1928 { } /* end */
1929};
1930
1931/* capture mixer elements */
f9e336f6
TI
1932static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1933 struct snd_ctl_elem_info *uinfo)
1934{
1935 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1936 struct alc_spec *spec = codec->spec;
1937 int err;
1da177e4 1938
5a9e02e9 1939 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1940 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1941 HDA_INPUT);
1942 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1943 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1944 return err;
1945}
1946
1947static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1948 unsigned int size, unsigned int __user *tlv)
1949{
1950 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1951 struct alc_spec *spec = codec->spec;
1952 int err;
1da177e4 1953
5a9e02e9 1954 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1955 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1956 HDA_INPUT);
1957 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1958 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1959 return err;
1960}
1961
1962typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1963 struct snd_ctl_elem_value *ucontrol);
1964
1965static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1966 struct snd_ctl_elem_value *ucontrol,
1967 getput_call_t func)
1968{
1969 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1970 struct alc_spec *spec = codec->spec;
1971 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1972 int err;
1973
5a9e02e9 1974 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1975 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1976 3, 0, HDA_INPUT);
1977 err = func(kcontrol, ucontrol);
5a9e02e9 1978 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1979 return err;
1980}
1981
1982static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1983 struct snd_ctl_elem_value *ucontrol)
1984{
1985 return alc_cap_getput_caller(kcontrol, ucontrol,
1986 snd_hda_mixer_amp_volume_get);
1987}
1988
1989static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1990 struct snd_ctl_elem_value *ucontrol)
1991{
1992 return alc_cap_getput_caller(kcontrol, ucontrol,
1993 snd_hda_mixer_amp_volume_put);
1994}
1995
1996/* capture mixer elements */
1997#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1998
1999static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2000 struct snd_ctl_elem_value *ucontrol)
2001{
2002 return alc_cap_getput_caller(kcontrol, ucontrol,
2003 snd_hda_mixer_amp_switch_get);
2004}
2005
2006static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2007 struct snd_ctl_elem_value *ucontrol)
2008{
2009 return alc_cap_getput_caller(kcontrol, ucontrol,
2010 snd_hda_mixer_amp_switch_put);
2011}
2012
a23b688f 2013#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2014 { \
2015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2016 .name = "Capture Switch", \
2017 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2018 .count = num, \
2019 .info = alc_cap_sw_info, \
2020 .get = alc_cap_sw_get, \
2021 .put = alc_cap_sw_put, \
2022 }, \
2023 { \
2024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2025 .name = "Capture Volume", \
2026 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2027 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2028 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2029 .count = num, \
2030 .info = alc_cap_vol_info, \
2031 .get = alc_cap_vol_get, \
2032 .put = alc_cap_vol_put, \
2033 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2034 }
2035
2036#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2037 { \
2038 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2039 /* .name = "Capture Source", */ \
2040 .name = "Input Source", \
2041 .count = num, \
2042 .info = alc_mux_enum_info, \
2043 .get = alc_mux_enum_get, \
2044 .put = alc_mux_enum_put, \
a23b688f
TI
2045 }
2046
2047#define DEFINE_CAPMIX(num) \
2048static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2049 _DEFINE_CAPMIX(num), \
2050 _DEFINE_CAPSRC(num), \
2051 { } /* end */ \
2052}
2053
2054#define DEFINE_CAPMIX_NOSRC(num) \
2055static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2056 _DEFINE_CAPMIX(num), \
2057 { } /* end */ \
f9e336f6
TI
2058}
2059
2060/* up to three ADCs */
2061DEFINE_CAPMIX(1);
2062DEFINE_CAPMIX(2);
2063DEFINE_CAPMIX(3);
a23b688f
TI
2064DEFINE_CAPMIX_NOSRC(1);
2065DEFINE_CAPMIX_NOSRC(2);
2066DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2067
2068/*
2069 * ALC880 5-stack model
2070 *
9c7f852e
TI
2071 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2072 * Side = 0x02 (0xd)
e9edcee0
TI
2073 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2074 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2075 */
2076
2077/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2078static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2079 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2080 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2081 { } /* end */
2082};
2083
e9edcee0
TI
2084/* channel source setting (6/8 channel selection for 5-stack) */
2085/* 6ch mode */
2086static struct hda_verb alc880_fivestack_ch6_init[] = {
2087 /* set line-in to input, mute it */
2088 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2089 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2090 { } /* end */
2091};
2092
e9edcee0
TI
2093/* 8ch mode */
2094static struct hda_verb alc880_fivestack_ch8_init[] = {
2095 /* set line-in to output, unmute it */
2096 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2097 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2098 { } /* end */
2099};
2100
d2a6d7dc 2101static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2102 { 6, alc880_fivestack_ch6_init },
2103 { 8, alc880_fivestack_ch8_init },
2104};
2105
2106
2107/*
2108 * ALC880 6-stack model
2109 *
9c7f852e
TI
2110 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2111 * Side = 0x05 (0x0f)
e9edcee0
TI
2112 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2113 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2114 */
2115
2116static hda_nid_t alc880_6st_dac_nids[4] = {
2117 /* front, rear, clfe, rear_surr */
2118 0x02, 0x03, 0x04, 0x05
f12ab1e0 2119};
e9edcee0
TI
2120
2121static struct hda_input_mux alc880_6stack_capture_source = {
2122 .num_items = 4,
2123 .items = {
2124 { "Mic", 0x0 },
2125 { "Front Mic", 0x1 },
2126 { "Line", 0x2 },
2127 { "CD", 0x4 },
2128 },
2129};
2130
2131/* fixed 8-channels */
d2a6d7dc 2132static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2133 { 8, NULL },
2134};
2135
c8b6bf9b 2136static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2137 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2138 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2139 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2140 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2141 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2142 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2143 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2144 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2145 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2146 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2149 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2150 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2152 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2153 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2154 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2155 {
2156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2157 .name = "Channel Mode",
df694daa
KY
2158 .info = alc_ch_mode_info,
2159 .get = alc_ch_mode_get,
2160 .put = alc_ch_mode_put,
16ded525
TI
2161 },
2162 { } /* end */
2163};
2164
e9edcee0
TI
2165
2166/*
2167 * ALC880 W810 model
2168 *
2169 * W810 has rear IO for:
2170 * Front (DAC 02)
2171 * Surround (DAC 03)
2172 * Center/LFE (DAC 04)
2173 * Digital out (06)
2174 *
2175 * The system also has a pair of internal speakers, and a headphone jack.
2176 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2177 *
e9edcee0
TI
2178 * There is a variable resistor to control the speaker or headphone
2179 * volume. This is a hardware-only device without a software API.
2180 *
2181 * Plugging headphones in will disable the internal speakers. This is
2182 * implemented in hardware, not via the driver using jack sense. In
2183 * a similar fashion, plugging into the rear socket marked "front" will
2184 * disable both the speakers and headphones.
2185 *
2186 * For input, there's a microphone jack, and an "audio in" jack.
2187 * These may not do anything useful with this driver yet, because I
2188 * haven't setup any initialization verbs for these yet...
2189 */
2190
2191static hda_nid_t alc880_w810_dac_nids[3] = {
2192 /* front, rear/surround, clfe */
2193 0x02, 0x03, 0x04
16ded525
TI
2194};
2195
e9edcee0 2196/* fixed 6 channels */
d2a6d7dc 2197static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2198 { 6, NULL }
2199};
2200
2201/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2202static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2205 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2206 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2207 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2212 { } /* end */
2213};
2214
2215
2216/*
2217 * Z710V model
2218 *
2219 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2220 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2221 * Line = 0x1a
e9edcee0
TI
2222 */
2223
2224static hda_nid_t alc880_z71v_dac_nids[1] = {
2225 0x02
2226};
2227#define ALC880_Z71V_HP_DAC 0x03
2228
2229/* fixed 2 channels */
d2a6d7dc 2230static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2231 { 2, NULL }
2232};
2233
c8b6bf9b 2234static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2235 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2236 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2237 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2238 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2239 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2240 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2243 { } /* end */
2244};
2245
e9edcee0 2246
e9edcee0
TI
2247/*
2248 * ALC880 F1734 model
2249 *
2250 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2251 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2252 */
2253
2254static hda_nid_t alc880_f1734_dac_nids[1] = {
2255 0x03
2256};
2257#define ALC880_F1734_HP_DAC 0x02
2258
c8b6bf9b 2259static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2261 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2262 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2263 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2264 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2265 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2268 { } /* end */
2269};
2270
937b4160
TI
2271static struct hda_input_mux alc880_f1734_capture_source = {
2272 .num_items = 2,
2273 .items = {
2274 { "Mic", 0x1 },
2275 { "CD", 0x4 },
2276 },
2277};
2278
e9edcee0 2279
e9edcee0
TI
2280/*
2281 * ALC880 ASUS model
2282 *
2283 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2284 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2285 * Mic = 0x18, Line = 0x1a
2286 */
2287
2288#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2289#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2290
c8b6bf9b 2291static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2292 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2293 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2294 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2295 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2296 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2297 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2298 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2306 {
2307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2308 .name = "Channel Mode",
df694daa
KY
2309 .info = alc_ch_mode_info,
2310 .get = alc_ch_mode_get,
2311 .put = alc_ch_mode_put,
16ded525
TI
2312 },
2313 { } /* end */
2314};
e9edcee0 2315
e9edcee0
TI
2316/*
2317 * ALC880 ASUS W1V model
2318 *
2319 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2320 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2321 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2322 */
2323
2324/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2325static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2326 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2327 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2328 { } /* end */
2329};
2330
df694daa
KY
2331/* TCL S700 */
2332static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2333 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2334 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
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("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2339 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2340 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2341 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2342 { } /* end */
2343};
2344
ccc656ce
KY
2345/* Uniwill */
2346static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2347 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2348 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2349 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2350 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2351 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2352 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2353 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2354 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2355 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2356 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2361 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2362 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2363 {
2364 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2365 .name = "Channel Mode",
2366 .info = alc_ch_mode_info,
2367 .get = alc_ch_mode_get,
2368 .put = alc_ch_mode_put,
2369 },
2370 { } /* end */
2371};
2372
2cf9f0fc
TD
2373static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2374 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2375 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2376 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2377 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2380 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2381 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2382 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2383 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2384 { } /* end */
2385};
2386
ccc656ce 2387static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2388 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2389 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2390 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2391 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2394 { } /* end */
2395};
2396
2134ea4f
TI
2397/*
2398 * virtual master controls
2399 */
2400
2401/*
2402 * slave controls for virtual master
2403 */
2404static const char *alc_slave_vols[] = {
2405 "Front Playback Volume",
2406 "Surround Playback Volume",
2407 "Center Playback Volume",
2408 "LFE Playback Volume",
2409 "Side Playback Volume",
2410 "Headphone Playback Volume",
2411 "Speaker Playback Volume",
2412 "Mono Playback Volume",
2134ea4f 2413 "Line-Out Playback Volume",
26f5df26 2414 "PCM Playback Volume",
2134ea4f
TI
2415 NULL,
2416};
2417
2418static const char *alc_slave_sws[] = {
2419 "Front Playback Switch",
2420 "Surround Playback Switch",
2421 "Center Playback Switch",
2422 "LFE Playback Switch",
2423 "Side Playback Switch",
2424 "Headphone Playback Switch",
2425 "Speaker Playback Switch",
2426 "Mono Playback Switch",
edb54a55 2427 "IEC958 Playback Switch",
23033b2b
TI
2428 "Line-Out Playback Switch",
2429 "PCM Playback Switch",
2134ea4f
TI
2430 NULL,
2431};
2432
1da177e4 2433/*
e9edcee0 2434 * build control elements
1da177e4 2435 */
603c4019 2436
5b0cb1d8
JK
2437#define NID_MAPPING (-1)
2438
2439#define SUBDEV_SPEAKER_ (0 << 6)
2440#define SUBDEV_HP_ (1 << 6)
2441#define SUBDEV_LINE_ (2 << 6)
2442#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2443#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2444#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2445
603c4019
TI
2446static void alc_free_kctls(struct hda_codec *codec);
2447
67d634c0 2448#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2449/* additional beep mixers; the actual parameters are overwritten at build */
2450static struct snd_kcontrol_new alc_beep_mixer[] = {
2451 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2452 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2453 { } /* end */
2454};
67d634c0 2455#endif
45bdd1c1 2456
1da177e4
LT
2457static int alc_build_controls(struct hda_codec *codec)
2458{
2459 struct alc_spec *spec = codec->spec;
5b0cb1d8
JK
2460 struct snd_kcontrol *kctl;
2461 struct snd_kcontrol_new *knew;
2462 int i, j, err;
2463 unsigned int u;
2464 hda_nid_t nid;
1da177e4
LT
2465
2466 for (i = 0; i < spec->num_mixers; i++) {
2467 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2468 if (err < 0)
2469 return err;
2470 }
f9e336f6
TI
2471 if (spec->cap_mixer) {
2472 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2473 if (err < 0)
2474 return err;
2475 }
1da177e4 2476 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2477 err = snd_hda_create_spdif_out_ctls(codec,
2478 spec->multiout.dig_out_nid);
1da177e4
LT
2479 if (err < 0)
2480 return err;
e64f14f4
TI
2481 if (!spec->no_analog) {
2482 err = snd_hda_create_spdif_share_sw(codec,
2483 &spec->multiout);
2484 if (err < 0)
2485 return err;
2486 spec->multiout.share_spdif = 1;
2487 }
1da177e4
LT
2488 }
2489 if (spec->dig_in_nid) {
2490 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2491 if (err < 0)
2492 return err;
2493 }
2134ea4f 2494
67d634c0 2495#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2496 /* create beep controls if needed */
2497 if (spec->beep_amp) {
2498 struct snd_kcontrol_new *knew;
2499 for (knew = alc_beep_mixer; knew->name; knew++) {
2500 struct snd_kcontrol *kctl;
2501 kctl = snd_ctl_new1(knew, codec);
2502 if (!kctl)
2503 return -ENOMEM;
2504 kctl->private_value = spec->beep_amp;
5e26dfd0 2505 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2506 if (err < 0)
2507 return err;
2508 }
2509 }
67d634c0 2510#endif
45bdd1c1 2511
2134ea4f 2512 /* if we have no master control, let's create it */
e64f14f4
TI
2513 if (!spec->no_analog &&
2514 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2515 unsigned int vmaster_tlv[4];
2134ea4f 2516 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2517 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2518 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2519 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2520 if (err < 0)
2521 return err;
2522 }
e64f14f4
TI
2523 if (!spec->no_analog &&
2524 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2525 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2526 NULL, alc_slave_sws);
2527 if (err < 0)
2528 return err;
2529 }
2530
603c4019 2531 alc_free_kctls(codec); /* no longer needed */
5b0cb1d8
JK
2532
2533 /* assign Capture Source enums to NID */
2534 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2535 if (!kctl)
2536 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2537 for (i = 0; kctl && i < kctl->count; i++) {
d1409ae4
TI
2538 hda_nid_t *nids = spec->capsrc_nids;
2539 if (!nids)
2540 nids = spec->adc_nids;
21949f00 2541 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
5b0cb1d8
JK
2542 if (err < 0)
2543 return err;
2544 }
2545 if (spec->cap_mixer) {
2546 const char *kname = kctl ? kctl->id.name : NULL;
2547 for (knew = spec->cap_mixer; knew->name; knew++) {
2548 if (kname && strcmp(knew->name, kname) == 0)
2549 continue;
2550 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2551 for (i = 0; kctl && i < kctl->count; i++) {
2552 err = snd_hda_add_nid(codec, kctl, i,
2553 spec->adc_nids[i]);
2554 if (err < 0)
2555 return err;
2556 }
2557 }
2558 }
2559
2560 /* other nid->control mapping */
2561 for (i = 0; i < spec->num_mixers; i++) {
2562 for (knew = spec->mixers[i]; knew->name; knew++) {
2563 if (knew->iface != NID_MAPPING)
2564 continue;
2565 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2566 if (kctl == NULL)
2567 continue;
2568 u = knew->subdevice;
2569 for (j = 0; j < 4; j++, u >>= 8) {
2570 nid = u & 0x3f;
2571 if (nid == 0)
2572 continue;
2573 switch (u & 0xc0) {
2574 case SUBDEV_SPEAKER_:
2575 nid = spec->autocfg.speaker_pins[nid];
2576 break;
2577 case SUBDEV_LINE_:
2578 nid = spec->autocfg.line_out_pins[nid];
2579 break;
2580 case SUBDEV_HP_:
2581 nid = spec->autocfg.hp_pins[nid];
2582 break;
2583 default:
2584 continue;
2585 }
2586 err = snd_hda_add_nid(codec, kctl, 0, nid);
2587 if (err < 0)
2588 return err;
2589 }
2590 u = knew->private_value;
2591 for (j = 0; j < 4; j++, u >>= 8) {
2592 nid = u & 0xff;
2593 if (nid == 0)
2594 continue;
2595 err = snd_hda_add_nid(codec, kctl, 0, nid);
2596 if (err < 0)
2597 return err;
2598 }
2599 }
2600 }
1da177e4
LT
2601 return 0;
2602}
2603
e9edcee0 2604
1da177e4
LT
2605/*
2606 * initialize the codec volumes, etc
2607 */
2608
e9edcee0
TI
2609/*
2610 * generic initialization of ADC, input mixers and output mixers
2611 */
2612static struct hda_verb alc880_volume_init_verbs[] = {
2613 /*
2614 * Unmute ADC0-2 and set the default input to mic-in
2615 */
71fe7b82 2616 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2618 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2620 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2622
e9edcee0
TI
2623 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2624 * mixer widget
9c7f852e
TI
2625 * Note: PASD motherboards uses the Line In 2 as the input for front
2626 * panel mic (mic 2)
1da177e4 2627 */
e9edcee0 2628 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2629 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2631 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2636
e9edcee0
TI
2637 /*
2638 * Set up output mixers (0x0c - 0x0f)
1da177e4 2639 */
e9edcee0
TI
2640 /* set vol=0 to output mixers */
2641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2643 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2644 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2645 /* set up input amps for analog loopback */
2646 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2654 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2655
2656 { }
2657};
2658
e9edcee0
TI
2659/*
2660 * 3-stack pin configuration:
2661 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2662 */
2663static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2664 /*
2665 * preset connection lists of input pins
2666 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2667 */
2668 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2669 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2670 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2671
2672 /*
2673 * Set pin mode and muting
2674 */
2675 /* set front pin widgets 0x14 for output */
05acb863 2676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2677 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2678 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2679 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2681 /* Mic2 (as headphone out) for HP output */
2682 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2683 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2684 /* Line In pin widget for input */
05acb863 2685 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2687 /* Line2 (as front mic) pin widget for input and vref at 80% */
2688 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2689 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2690 /* CD pin widget for input */
05acb863 2691 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2692
e9edcee0
TI
2693 { }
2694};
1da177e4 2695
e9edcee0
TI
2696/*
2697 * 5-stack pin configuration:
2698 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2699 * line-in/side = 0x1a, f-mic = 0x1b
2700 */
2701static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2702 /*
2703 * preset connection lists of input pins
2704 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2705 */
e9edcee0
TI
2706 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2707 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2708
e9edcee0
TI
2709 /*
2710 * Set pin mode and muting
1da177e4 2711 */
e9edcee0
TI
2712 /* set pin widgets 0x14-0x17 for output */
2713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2715 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2716 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2717 /* unmute pins for output (no gain on this amp) */
2718 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2719 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2720 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2721 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2722
2723 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2724 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2725 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2726 /* Mic2 (as headphone out) for HP output */
2727 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2728 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2729 /* Line In pin widget for input */
2730 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2731 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2732 /* Line2 (as front mic) pin widget for input and vref at 80% */
2733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2734 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2735 /* CD pin widget for input */
2736 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2737
2738 { }
2739};
2740
e9edcee0
TI
2741/*
2742 * W810 pin configuration:
2743 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2744 */
2745static struct hda_verb alc880_pin_w810_init_verbs[] = {
2746 /* hphone/speaker input selector: front DAC */
2747 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2748
05acb863 2749 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2750 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2753 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2754 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2755
e9edcee0 2756 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2757 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2758
1da177e4
LT
2759 { }
2760};
2761
e9edcee0
TI
2762/*
2763 * Z71V pin configuration:
2764 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2765 */
2766static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2767 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2769 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2771
16ded525 2772 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2774 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2775 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2776
2777 { }
2778};
2779
e9edcee0
TI
2780/*
2781 * 6-stack pin configuration:
9c7f852e
TI
2782 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2783 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2784 */
2785static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2786 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2787
16ded525 2788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2789 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2790 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2791 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2792 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2794 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2795 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796
16ded525 2797 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2799 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2800 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2801 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2802 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2803 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2804 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2805 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2806
e9edcee0
TI
2807 { }
2808};
2809
ccc656ce
KY
2810/*
2811 * Uniwill pin configuration:
2812 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2813 * line = 0x1a
2814 */
2815static struct hda_verb alc880_uniwill_init_verbs[] = {
2816 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2817
2818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2822 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2823 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2824 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2825 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2827 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2828 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2829 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2830 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2831 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2832
2833 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2835 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2837 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2839 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2840 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2841 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2842
2843 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2844 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2845
2846 { }
2847};
2848
2849/*
2850* Uniwill P53
ea1fb29a 2851* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2852 */
2853static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2854 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2855
2856 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2857 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2860 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2861 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2862 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2864 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2866 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2868
2869 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2870 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2871 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2872 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2873 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2875
2876 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2877 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2878
2879 { }
2880};
2881
2cf9f0fc
TD
2882static struct hda_verb alc880_beep_init_verbs[] = {
2883 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2884 { }
2885};
2886
458a4fab
TI
2887/* auto-toggle front mic */
2888static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2889{
2890 unsigned int present;
2891 unsigned char bits;
ccc656ce 2892
864f92be 2893 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
2894 bits = present ? HDA_AMP_MUTE : 0;
2895 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2896}
2897
4f5d1706 2898static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 2899{
a9fd4f3f
TI
2900 struct alc_spec *spec = codec->spec;
2901
2902 spec->autocfg.hp_pins[0] = 0x14;
2903 spec->autocfg.speaker_pins[0] = 0x15;
2904 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
2905}
2906
2907static void alc880_uniwill_init_hook(struct hda_codec *codec)
2908{
a9fd4f3f 2909 alc_automute_amp(codec);
458a4fab 2910 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2911}
2912
2913static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2914 unsigned int res)
2915{
2916 /* Looks like the unsol event is incompatible with the standard
2917 * definition. 4bit tag is placed at 28 bit!
2918 */
458a4fab 2919 switch (res >> 28) {
458a4fab
TI
2920 case ALC880_MIC_EVENT:
2921 alc880_uniwill_mic_automute(codec);
2922 break;
a9fd4f3f
TI
2923 default:
2924 alc_automute_amp_unsol_event(codec, res);
2925 break;
458a4fab 2926 }
ccc656ce
KY
2927}
2928
4f5d1706 2929static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 2930{
a9fd4f3f 2931 struct alc_spec *spec = codec->spec;
ccc656ce 2932
a9fd4f3f
TI
2933 spec->autocfg.hp_pins[0] = 0x14;
2934 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
2935}
2936
2937static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2938{
2939 unsigned int present;
ea1fb29a 2940
ccc656ce 2941 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2942 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2943 present &= HDA_AMP_VOLMASK;
2944 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2945 HDA_AMP_VOLMASK, present);
2946 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2947 HDA_AMP_VOLMASK, present);
ccc656ce 2948}
47fd830a 2949
ccc656ce
KY
2950static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2951 unsigned int res)
2952{
2953 /* Looks like the unsol event is incompatible with the standard
2954 * definition. 4bit tag is placed at 28 bit!
2955 */
f12ab1e0 2956 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 2957 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
2958 else
2959 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
2960}
2961
e9edcee0
TI
2962/*
2963 * F1734 pin configuration:
2964 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2965 */
2966static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2967 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2968 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2969 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2970 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2971 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2972
e9edcee0 2973 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2974 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2977
e9edcee0
TI
2978 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2979 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2980 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2981 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2982 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2983 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2984 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2985 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2986 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2987
937b4160
TI
2988 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2989 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2990
dfc0ff62
TI
2991 { }
2992};
2993
e9edcee0
TI
2994/*
2995 * ASUS pin configuration:
2996 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2997 */
2998static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2999 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3000 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3001 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3002 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3003
3004 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3005 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3007 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3008 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3010 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3012
3013 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3014 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3015 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3016 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3017 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3018 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3019 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3020 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3021 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3022
e9edcee0
TI
3023 { }
3024};
16ded525 3025
e9edcee0 3026/* Enable GPIO mask and set output */
bc9f98a9
KY
3027#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3028#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3029#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3030
3031/* Clevo m520g init */
3032static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3033 /* headphone output */
3034 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3035 /* line-out */
3036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3037 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3038 /* Line-in */
3039 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3040 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3041 /* CD */
3042 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3043 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3044 /* Mic1 (rear panel) */
3045 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3046 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3047 /* Mic2 (front panel) */
3048 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3049 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3050 /* headphone */
3051 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3052 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3053 /* change to EAPD mode */
3054 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3055 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3056
3057 { }
16ded525
TI
3058};
3059
df694daa 3060static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3061 /* change to EAPD mode */
3062 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3063 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3064
df694daa
KY
3065 /* Headphone output */
3066 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3067 /* Front output*/
3068 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3069 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3070
3071 /* Line In pin widget for input */
3072 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3073 /* CD pin widget for input */
3074 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3075 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3076 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3077
3078 /* change to EAPD mode */
3079 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3080 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3081
3082 { }
3083};
16ded525 3084
e9edcee0 3085/*
ae6b813a
TI
3086 * LG m1 express dual
3087 *
3088 * Pin assignment:
3089 * Rear Line-In/Out (blue): 0x14
3090 * Build-in Mic-In: 0x15
3091 * Speaker-out: 0x17
3092 * HP-Out (green): 0x1b
3093 * Mic-In/Out (red): 0x19
3094 * SPDIF-Out: 0x1e
3095 */
3096
3097/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3098static hda_nid_t alc880_lg_dac_nids[3] = {
3099 0x05, 0x02, 0x03
3100};
3101
3102/* seems analog CD is not working */
3103static struct hda_input_mux alc880_lg_capture_source = {
3104 .num_items = 3,
3105 .items = {
3106 { "Mic", 0x1 },
3107 { "Line", 0x5 },
3108 { "Internal Mic", 0x6 },
3109 },
3110};
3111
3112/* 2,4,6 channel modes */
3113static struct hda_verb alc880_lg_ch2_init[] = {
3114 /* set line-in and mic-in to input */
3115 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3116 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3117 { }
3118};
3119
3120static struct hda_verb alc880_lg_ch4_init[] = {
3121 /* set line-in to out and mic-in to input */
3122 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3123 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3124 { }
3125};
3126
3127static struct hda_verb alc880_lg_ch6_init[] = {
3128 /* set line-in and mic-in to output */
3129 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3130 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3131 { }
3132};
3133
3134static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3135 { 2, alc880_lg_ch2_init },
3136 { 4, alc880_lg_ch4_init },
3137 { 6, alc880_lg_ch6_init },
3138};
3139
3140static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3141 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3142 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3143 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3144 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3145 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3146 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3147 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3148 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3151 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3152 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3153 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3154 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3155 {
3156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3157 .name = "Channel Mode",
3158 .info = alc_ch_mode_info,
3159 .get = alc_ch_mode_get,
3160 .put = alc_ch_mode_put,
3161 },
3162 { } /* end */
3163};
3164
3165static struct hda_verb alc880_lg_init_verbs[] = {
3166 /* set capture source to mic-in */
3167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3168 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3169 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3170 /* mute all amp mixer inputs */
3171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3174 /* line-in to input */
3175 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3176 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3177 /* built-in mic */
3178 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3179 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3180 /* speaker-out */
3181 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3182 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3183 /* mic-in to input */
3184 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3186 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3187 /* HP-out */
3188 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3189 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3190 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3191 /* jack sense */
a9fd4f3f 3192 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3193 { }
3194};
3195
3196/* toggle speaker-output according to the hp-jack state */
4f5d1706 3197static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3198{
a9fd4f3f 3199 struct alc_spec *spec = codec->spec;
ae6b813a 3200
a9fd4f3f
TI
3201 spec->autocfg.hp_pins[0] = 0x1b;
3202 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3203}
3204
d681518a
TI
3205/*
3206 * LG LW20
3207 *
3208 * Pin assignment:
3209 * Speaker-out: 0x14
3210 * Mic-In: 0x18
e4f41da9
CM
3211 * Built-in Mic-In: 0x19
3212 * Line-In: 0x1b
3213 * HP-Out: 0x1a
d681518a
TI
3214 * SPDIF-Out: 0x1e
3215 */
3216
d681518a 3217static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3218 .num_items = 3,
d681518a
TI
3219 .items = {
3220 { "Mic", 0x0 },
3221 { "Internal Mic", 0x1 },
e4f41da9 3222 { "Line In", 0x2 },
d681518a
TI
3223 },
3224};
3225
0a8c5da3
CM
3226#define alc880_lg_lw_modes alc880_threestack_modes
3227
d681518a 3228static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3229 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3230 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3232 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3233 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3234 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3235 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3236 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3237 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3238 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3241 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3242 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3243 {
3244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3245 .name = "Channel Mode",
3246 .info = alc_ch_mode_info,
3247 .get = alc_ch_mode_get,
3248 .put = alc_ch_mode_put,
3249 },
d681518a
TI
3250 { } /* end */
3251};
3252
3253static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3254 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3255 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3256 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3257
d681518a
TI
3258 /* set capture source to mic-in */
3259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3260 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3262 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3263 /* speaker-out */
3264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3265 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3266 /* HP-out */
d681518a
TI
3267 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3268 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3269 /* mic-in to input */
3270 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3271 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3272 /* built-in mic */
3273 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3274 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3275 /* jack sense */
a9fd4f3f 3276 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3277 { }
3278};
3279
3280/* toggle speaker-output according to the hp-jack state */
4f5d1706 3281static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3282{
a9fd4f3f 3283 struct alc_spec *spec = codec->spec;
d681518a 3284
a9fd4f3f
TI
3285 spec->autocfg.hp_pins[0] = 0x1b;
3286 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3287}
3288
df99cd33
TI
3289static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3290 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3291 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3292 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3293 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3294 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3295 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3296 { } /* end */
3297};
3298
3299static struct hda_input_mux alc880_medion_rim_capture_source = {
3300 .num_items = 2,
3301 .items = {
3302 { "Mic", 0x0 },
3303 { "Internal Mic", 0x1 },
3304 },
3305};
3306
3307static struct hda_verb alc880_medion_rim_init_verbs[] = {
3308 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3309
3310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3311 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3312
3313 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3314 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3316 /* Mic2 (as headphone out) for HP output */
3317 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3318 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3319 /* Internal Speaker */
3320 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3322
3323 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3324 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3325
3326 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3327 { }
3328};
3329
3330/* toggle speaker-output according to the hp-jack state */
3331static void alc880_medion_rim_automute(struct hda_codec *codec)
3332{
a9fd4f3f
TI
3333 struct alc_spec *spec = codec->spec;
3334 alc_automute_amp(codec);
3335 /* toggle EAPD */
3336 if (spec->jack_present)
df99cd33
TI
3337 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3338 else
3339 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3340}
3341
3342static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3343 unsigned int res)
3344{
3345 /* Looks like the unsol event is incompatible with the standard
3346 * definition. 4bit tag is placed at 28 bit!
3347 */
3348 if ((res >> 28) == ALC880_HP_EVENT)
3349 alc880_medion_rim_automute(codec);
3350}
3351
4f5d1706 3352static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3353{
3354 struct alc_spec *spec = codec->spec;
3355
3356 spec->autocfg.hp_pins[0] = 0x14;
3357 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3358}
3359
cb53c626
TI
3360#ifdef CONFIG_SND_HDA_POWER_SAVE
3361static struct hda_amp_list alc880_loopbacks[] = {
3362 { 0x0b, HDA_INPUT, 0 },
3363 { 0x0b, HDA_INPUT, 1 },
3364 { 0x0b, HDA_INPUT, 2 },
3365 { 0x0b, HDA_INPUT, 3 },
3366 { 0x0b, HDA_INPUT, 4 },
3367 { } /* end */
3368};
3369
3370static struct hda_amp_list alc880_lg_loopbacks[] = {
3371 { 0x0b, HDA_INPUT, 1 },
3372 { 0x0b, HDA_INPUT, 6 },
3373 { 0x0b, HDA_INPUT, 7 },
3374 { } /* end */
3375};
3376#endif
3377
ae6b813a
TI
3378/*
3379 * Common callbacks
e9edcee0
TI
3380 */
3381
1da177e4
LT
3382static int alc_init(struct hda_codec *codec)
3383{
3384 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3385 unsigned int i;
3386
2c3bf9ab 3387 alc_fix_pll(codec);
4a79ba34 3388 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3389
e9edcee0
TI
3390 for (i = 0; i < spec->num_init_verbs; i++)
3391 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3392
3393 if (spec->init_hook)
3394 spec->init_hook(codec);
3395
1da177e4
LT
3396 return 0;
3397}
3398
ae6b813a
TI
3399static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3400{
3401 struct alc_spec *spec = codec->spec;
3402
3403 if (spec->unsol_event)
3404 spec->unsol_event(codec, res);
3405}
3406
cb53c626
TI
3407#ifdef CONFIG_SND_HDA_POWER_SAVE
3408static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3409{
3410 struct alc_spec *spec = codec->spec;
3411 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3412}
3413#endif
3414
1da177e4
LT
3415/*
3416 * Analog playback callbacks
3417 */
3418static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3419 struct hda_codec *codec,
c8b6bf9b 3420 struct snd_pcm_substream *substream)
1da177e4
LT
3421{
3422 struct alc_spec *spec = codec->spec;
9a08160b
TI
3423 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3424 hinfo);
1da177e4
LT
3425}
3426
3427static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3428 struct hda_codec *codec,
3429 unsigned int stream_tag,
3430 unsigned int format,
c8b6bf9b 3431 struct snd_pcm_substream *substream)
1da177e4
LT
3432{
3433 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3434 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3435 stream_tag, format, substream);
1da177e4
LT
3436}
3437
3438static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3439 struct hda_codec *codec,
c8b6bf9b 3440 struct snd_pcm_substream *substream)
1da177e4
LT
3441{
3442 struct alc_spec *spec = codec->spec;
3443 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3444}
3445
3446/*
3447 * Digital out
3448 */
3449static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3450 struct hda_codec *codec,
c8b6bf9b 3451 struct snd_pcm_substream *substream)
1da177e4
LT
3452{
3453 struct alc_spec *spec = codec->spec;
3454 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3455}
3456
6b97eb45
TI
3457static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3458 struct hda_codec *codec,
3459 unsigned int stream_tag,
3460 unsigned int format,
3461 struct snd_pcm_substream *substream)
3462{
3463 struct alc_spec *spec = codec->spec;
3464 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3465 stream_tag, format, substream);
3466}
3467
9b5f12e5
TI
3468static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3469 struct hda_codec *codec,
3470 struct snd_pcm_substream *substream)
3471{
3472 struct alc_spec *spec = codec->spec;
3473 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3474}
3475
1da177e4
LT
3476static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3477 struct hda_codec *codec,
c8b6bf9b 3478 struct snd_pcm_substream *substream)
1da177e4
LT
3479{
3480 struct alc_spec *spec = codec->spec;
3481 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3482}
3483
3484/*
3485 * Analog capture
3486 */
6330079f 3487static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3488 struct hda_codec *codec,
3489 unsigned int stream_tag,
3490 unsigned int format,
c8b6bf9b 3491 struct snd_pcm_substream *substream)
1da177e4
LT
3492{
3493 struct alc_spec *spec = codec->spec;
3494
6330079f 3495 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3496 stream_tag, 0, format);
3497 return 0;
3498}
3499
6330079f 3500static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3501 struct hda_codec *codec,
c8b6bf9b 3502 struct snd_pcm_substream *substream)
1da177e4
LT
3503{
3504 struct alc_spec *spec = codec->spec;
3505
888afa15
TI
3506 snd_hda_codec_cleanup_stream(codec,
3507 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3508 return 0;
3509}
3510
3511
3512/*
3513 */
3514static struct hda_pcm_stream alc880_pcm_analog_playback = {
3515 .substreams = 1,
3516 .channels_min = 2,
3517 .channels_max = 8,
e9edcee0 3518 /* NID is set in alc_build_pcms */
1da177e4
LT
3519 .ops = {
3520 .open = alc880_playback_pcm_open,
3521 .prepare = alc880_playback_pcm_prepare,
3522 .cleanup = alc880_playback_pcm_cleanup
3523 },
3524};
3525
3526static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3527 .substreams = 1,
3528 .channels_min = 2,
3529 .channels_max = 2,
3530 /* NID is set in alc_build_pcms */
3531};
3532
3533static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3534 .substreams = 1,
3535 .channels_min = 2,
3536 .channels_max = 2,
3537 /* NID is set in alc_build_pcms */
3538};
3539
3540static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3541 .substreams = 2, /* can be overridden */
1da177e4
LT
3542 .channels_min = 2,
3543 .channels_max = 2,
e9edcee0 3544 /* NID is set in alc_build_pcms */
1da177e4 3545 .ops = {
6330079f
TI
3546 .prepare = alc880_alt_capture_pcm_prepare,
3547 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3548 },
3549};
3550
3551static struct hda_pcm_stream alc880_pcm_digital_playback = {
3552 .substreams = 1,
3553 .channels_min = 2,
3554 .channels_max = 2,
3555 /* NID is set in alc_build_pcms */
3556 .ops = {
3557 .open = alc880_dig_playback_pcm_open,
6b97eb45 3558 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3559 .prepare = alc880_dig_playback_pcm_prepare,
3560 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3561 },
3562};
3563
3564static struct hda_pcm_stream alc880_pcm_digital_capture = {
3565 .substreams = 1,
3566 .channels_min = 2,
3567 .channels_max = 2,
3568 /* NID is set in alc_build_pcms */
3569};
3570
4c5186ed 3571/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3572static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3573 .substreams = 0,
3574 .channels_min = 0,
3575 .channels_max = 0,
3576};
3577
1da177e4
LT
3578static int alc_build_pcms(struct hda_codec *codec)
3579{
3580 struct alc_spec *spec = codec->spec;
3581 struct hda_pcm *info = spec->pcm_rec;
3582 int i;
3583
3584 codec->num_pcms = 1;
3585 codec->pcm_info = info;
3586
e64f14f4
TI
3587 if (spec->no_analog)
3588 goto skip_analog;
3589
812a2cca
TI
3590 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3591 "%s Analog", codec->chip_name);
1da177e4 3592 info->name = spec->stream_name_analog;
274693f3 3593
4a471b7d 3594 if (spec->stream_analog_playback) {
da3cec35
TI
3595 if (snd_BUG_ON(!spec->multiout.dac_nids))
3596 return -EINVAL;
4a471b7d
TI
3597 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3598 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3599 }
3600 if (spec->stream_analog_capture) {
da3cec35
TI
3601 if (snd_BUG_ON(!spec->adc_nids))
3602 return -EINVAL;
4a471b7d
TI
3603 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3604 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3605 }
3606
3607 if (spec->channel_mode) {
3608 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3609 for (i = 0; i < spec->num_channel_mode; i++) {
3610 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3611 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3612 }
1da177e4
LT
3613 }
3614 }
3615
e64f14f4 3616 skip_analog:
e08a007d 3617 /* SPDIF for stream index #1 */
1da177e4 3618 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3619 snprintf(spec->stream_name_digital,
3620 sizeof(spec->stream_name_digital),
3621 "%s Digital", codec->chip_name);
e08a007d 3622 codec->num_pcms = 2;
b25c9da1 3623 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3624 info = spec->pcm_rec + 1;
1da177e4 3625 info->name = spec->stream_name_digital;
8c441982
TI
3626 if (spec->dig_out_type)
3627 info->pcm_type = spec->dig_out_type;
3628 else
3629 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3630 if (spec->multiout.dig_out_nid &&
3631 spec->stream_digital_playback) {
1da177e4
LT
3632 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3633 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3634 }
4a471b7d
TI
3635 if (spec->dig_in_nid &&
3636 spec->stream_digital_capture) {
1da177e4
LT
3637 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3638 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3639 }
963f803f
TI
3640 /* FIXME: do we need this for all Realtek codec models? */
3641 codec->spdif_status_reset = 1;
1da177e4
LT
3642 }
3643
e64f14f4
TI
3644 if (spec->no_analog)
3645 return 0;
3646
e08a007d
TI
3647 /* If the use of more than one ADC is requested for the current
3648 * model, configure a second analog capture-only PCM.
3649 */
3650 /* Additional Analaog capture for index #2 */
6330079f
TI
3651 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3652 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3653 codec->num_pcms = 3;
c06134d7 3654 info = spec->pcm_rec + 2;
e08a007d 3655 info->name = spec->stream_name_analog;
6330079f
TI
3656 if (spec->alt_dac_nid) {
3657 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3658 *spec->stream_analog_alt_playback;
3659 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3660 spec->alt_dac_nid;
3661 } else {
3662 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3663 alc_pcm_null_stream;
3664 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3665 }
3666 if (spec->num_adc_nids > 1) {
3667 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3668 *spec->stream_analog_alt_capture;
3669 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3670 spec->adc_nids[1];
3671 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3672 spec->num_adc_nids - 1;
3673 } else {
3674 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3675 alc_pcm_null_stream;
3676 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3677 }
3678 }
3679
1da177e4
LT
3680 return 0;
3681}
3682
a4e09aa3
TI
3683static inline void alc_shutup(struct hda_codec *codec)
3684{
3685 snd_hda_shutup_pins(codec);
3686}
3687
603c4019
TI
3688static void alc_free_kctls(struct hda_codec *codec)
3689{
3690 struct alc_spec *spec = codec->spec;
3691
3692 if (spec->kctls.list) {
3693 struct snd_kcontrol_new *kctl = spec->kctls.list;
3694 int i;
3695 for (i = 0; i < spec->kctls.used; i++)
3696 kfree(kctl[i].name);
3697 }
3698 snd_array_free(&spec->kctls);
3699}
3700
1da177e4
LT
3701static void alc_free(struct hda_codec *codec)
3702{
e9edcee0 3703 struct alc_spec *spec = codec->spec;
e9edcee0 3704
f12ab1e0 3705 if (!spec)
e9edcee0
TI
3706 return;
3707
a4e09aa3 3708 alc_shutup(codec);
603c4019 3709 alc_free_kctls(codec);
e9edcee0 3710 kfree(spec);
680cd536 3711 snd_hda_detach_beep_device(codec);
1da177e4
LT
3712}
3713
f5de24b0 3714#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3715static void alc_power_eapd(struct hda_codec *codec)
3716{
3717 /* We currently only handle front, HP */
3718 switch (codec->vendor_id) {
3719 case 0x10ec0260:
9e4c8496
TI
3720 set_eapd(codec, 0x0f, 0);
3721 set_eapd(codec, 0x10, 0);
c97259df
DC
3722 break;
3723 case 0x10ec0262:
3724 case 0x10ec0267:
3725 case 0x10ec0268:
3726 case 0x10ec0269:
9e4c8496 3727 case 0x10ec0270:
c97259df
DC
3728 case 0x10ec0272:
3729 case 0x10ec0660:
3730 case 0x10ec0662:
3731 case 0x10ec0663:
3732 case 0x10ec0862:
3733 case 0x10ec0889:
9e4c8496
TI
3734 set_eapd(codec, 0x14, 0);
3735 set_eapd(codec, 0x15, 0);
c97259df
DC
3736 break;
3737 }
3738}
3739
f5de24b0
HM
3740static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3741{
3742 struct alc_spec *spec = codec->spec;
a4e09aa3 3743 alc_shutup(codec);
f5de24b0 3744 if (spec && spec->power_hook)
c97259df 3745 spec->power_hook(codec);
f5de24b0
HM
3746 return 0;
3747}
3748#endif
3749
e044c39a 3750#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3751static int alc_resume(struct hda_codec *codec)
3752{
e044c39a
TI
3753 codec->patch_ops.init(codec);
3754 snd_hda_codec_resume_amp(codec);
3755 snd_hda_codec_resume_cache(codec);
3756 return 0;
3757}
e044c39a
TI
3758#endif
3759
1da177e4
LT
3760/*
3761 */
3762static struct hda_codec_ops alc_patch_ops = {
3763 .build_controls = alc_build_controls,
3764 .build_pcms = alc_build_pcms,
3765 .init = alc_init,
3766 .free = alc_free,
ae6b813a 3767 .unsol_event = alc_unsol_event,
e044c39a
TI
3768#ifdef SND_HDA_NEEDS_RESUME
3769 .resume = alc_resume,
3770#endif
cb53c626 3771#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 3772 .suspend = alc_suspend,
cb53c626
TI
3773 .check_power_status = alc_check_power_status,
3774#endif
c97259df 3775 .reboot_notify = alc_shutup,
1da177e4
LT
3776};
3777
2fa522be
TI
3778
3779/*
3780 * Test configuration for debugging
3781 *
3782 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3783 * enum controls.
3784 */
3785#ifdef CONFIG_SND_DEBUG
3786static hda_nid_t alc880_test_dac_nids[4] = {
3787 0x02, 0x03, 0x04, 0x05
3788};
3789
3790static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3791 .num_items = 7,
2fa522be
TI
3792 .items = {
3793 { "In-1", 0x0 },
3794 { "In-2", 0x1 },
3795 { "In-3", 0x2 },
3796 { "In-4", 0x3 },
3797 { "CD", 0x4 },
ae6b813a
TI
3798 { "Front", 0x5 },
3799 { "Surround", 0x6 },
2fa522be
TI
3800 },
3801};
3802
d2a6d7dc 3803static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3804 { 2, NULL },
fd2c326d 3805 { 4, NULL },
2fa522be 3806 { 6, NULL },
fd2c326d 3807 { 8, NULL },
2fa522be
TI
3808};
3809
9c7f852e
TI
3810static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3811 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3812{
3813 static char *texts[] = {
3814 "N/A", "Line Out", "HP Out",
3815 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3816 };
3817 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3818 uinfo->count = 1;
3819 uinfo->value.enumerated.items = 8;
3820 if (uinfo->value.enumerated.item >= 8)
3821 uinfo->value.enumerated.item = 7;
3822 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3823 return 0;
3824}
3825
9c7f852e
TI
3826static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3827 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3828{
3829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3830 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3831 unsigned int pin_ctl, item = 0;
3832
3833 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3834 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3835 if (pin_ctl & AC_PINCTL_OUT_EN) {
3836 if (pin_ctl & AC_PINCTL_HP_EN)
3837 item = 2;
3838 else
3839 item = 1;
3840 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3841 switch (pin_ctl & AC_PINCTL_VREFEN) {
3842 case AC_PINCTL_VREF_HIZ: item = 3; break;
3843 case AC_PINCTL_VREF_50: item = 4; break;
3844 case AC_PINCTL_VREF_GRD: item = 5; break;
3845 case AC_PINCTL_VREF_80: item = 6; break;
3846 case AC_PINCTL_VREF_100: item = 7; break;
3847 }
3848 }
3849 ucontrol->value.enumerated.item[0] = item;
3850 return 0;
3851}
3852
9c7f852e
TI
3853static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3854 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3855{
3856 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3857 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3858 static unsigned int ctls[] = {
3859 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3860 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3861 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3862 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3863 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3864 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3865 };
3866 unsigned int old_ctl, new_ctl;
3867
3868 old_ctl = snd_hda_codec_read(codec, nid, 0,
3869 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3870 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3871 if (old_ctl != new_ctl) {
82beb8fd
TI
3872 int val;
3873 snd_hda_codec_write_cache(codec, nid, 0,
3874 AC_VERB_SET_PIN_WIDGET_CONTROL,
3875 new_ctl);
47fd830a
TI
3876 val = ucontrol->value.enumerated.item[0] >= 3 ?
3877 HDA_AMP_MUTE : 0;
3878 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3879 HDA_AMP_MUTE, val);
2fa522be
TI
3880 return 1;
3881 }
3882 return 0;
3883}
3884
9c7f852e
TI
3885static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3886 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3887{
3888 static char *texts[] = {
3889 "Front", "Surround", "CLFE", "Side"
3890 };
3891 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3892 uinfo->count = 1;
3893 uinfo->value.enumerated.items = 4;
3894 if (uinfo->value.enumerated.item >= 4)
3895 uinfo->value.enumerated.item = 3;
3896 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3897 return 0;
3898}
3899
9c7f852e
TI
3900static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3901 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3902{
3903 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3904 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3905 unsigned int sel;
3906
3907 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3908 ucontrol->value.enumerated.item[0] = sel & 3;
3909 return 0;
3910}
3911
9c7f852e
TI
3912static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3913 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3914{
3915 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3916 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3917 unsigned int sel;
3918
3919 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3920 if (ucontrol->value.enumerated.item[0] != sel) {
3921 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3922 snd_hda_codec_write_cache(codec, nid, 0,
3923 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3924 return 1;
3925 }
3926 return 0;
3927}
3928
3929#define PIN_CTL_TEST(xname,nid) { \
3930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3931 .name = xname, \
5b0cb1d8 3932 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
3933 .info = alc_test_pin_ctl_info, \
3934 .get = alc_test_pin_ctl_get, \
3935 .put = alc_test_pin_ctl_put, \
3936 .private_value = nid \
3937 }
3938
3939#define PIN_SRC_TEST(xname,nid) { \
3940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3941 .name = xname, \
5b0cb1d8 3942 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
3943 .info = alc_test_pin_src_info, \
3944 .get = alc_test_pin_src_get, \
3945 .put = alc_test_pin_src_put, \
3946 .private_value = nid \
3947 }
3948
c8b6bf9b 3949static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3950 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3951 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3952 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3953 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3954 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3955 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3956 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3957 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3958 PIN_CTL_TEST("Front Pin Mode", 0x14),
3959 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3960 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3961 PIN_CTL_TEST("Side Pin Mode", 0x17),
3962 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3963 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3964 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3965 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3966 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3967 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3968 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3969 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3970 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3971 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3972 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3973 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3974 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3975 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3976 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3977 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3980 {
3981 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3982 .name = "Channel Mode",
df694daa
KY
3983 .info = alc_ch_mode_info,
3984 .get = alc_ch_mode_get,
3985 .put = alc_ch_mode_put,
2fa522be
TI
3986 },
3987 { } /* end */
3988};
3989
3990static struct hda_verb alc880_test_init_verbs[] = {
3991 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3992 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3993 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3994 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3995 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4000 /* Vol output for 0x0c-0x0f */
05acb863
TI
4001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4002 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4003 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4005 /* Set output pins 0x14-0x17 */
05acb863
TI
4006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4008 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4009 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4010 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4013 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4014 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4015 /* Set input pins 0x18-0x1c */
16ded525
TI
4016 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4018 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4019 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4020 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4021 /* Mute input pins 0x18-0x1b */
05acb863
TI
4022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4023 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4024 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4025 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4026 /* ADC set up */
05acb863 4027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4028 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4029 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4030 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4031 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4032 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4033 /* Analog input/passthru */
4034 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4035 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4036 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4037 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4039 { }
4040};
4041#endif
4042
1da177e4
LT
4043/*
4044 */
4045
f5fcc13c
TI
4046static const char *alc880_models[ALC880_MODEL_LAST] = {
4047 [ALC880_3ST] = "3stack",
4048 [ALC880_TCL_S700] = "tcl",
4049 [ALC880_3ST_DIG] = "3stack-digout",
4050 [ALC880_CLEVO] = "clevo",
4051 [ALC880_5ST] = "5stack",
4052 [ALC880_5ST_DIG] = "5stack-digout",
4053 [ALC880_W810] = "w810",
4054 [ALC880_Z71V] = "z71v",
4055 [ALC880_6ST] = "6stack",
4056 [ALC880_6ST_DIG] = "6stack-digout",
4057 [ALC880_ASUS] = "asus",
4058 [ALC880_ASUS_W1V] = "asus-w1v",
4059 [ALC880_ASUS_DIG] = "asus-dig",
4060 [ALC880_ASUS_DIG2] = "asus-dig2",
4061 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4062 [ALC880_UNIWILL_P53] = "uniwill-p53",
4063 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4064 [ALC880_F1734] = "F1734",
4065 [ALC880_LG] = "lg",
4066 [ALC880_LG_LW] = "lg-lw",
df99cd33 4067 [ALC880_MEDION_RIM] = "medion",
2fa522be 4068#ifdef CONFIG_SND_DEBUG
f5fcc13c 4069 [ALC880_TEST] = "test",
2fa522be 4070#endif
f5fcc13c
TI
4071 [ALC880_AUTO] = "auto",
4072};
4073
4074static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4075 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4076 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4077 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4078 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4079 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4080 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4081 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4082 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4083 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4084 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4085 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4086 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4087 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4088 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4089 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4090 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4091 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4092 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4093 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4094 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4095 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4096 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4097 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4098 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4099 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4100 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4101 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4102 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4103 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4104 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4105 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4106 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4107 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4108 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4109 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4110 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4111 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4112 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4113 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4114 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4115 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4116 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4117 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4118 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4119 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4120 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4121 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4122 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4123 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 4124 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 4125 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4126 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4127 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4128 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4129 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4130 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4131 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4132 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4133 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4134 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4135 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4136 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4137 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4138 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4139 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4140 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4141 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4142 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4143 /* default Intel */
4144 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4145 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4146 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4147 {}
4148};
4149
16ded525 4150/*
df694daa 4151 * ALC880 codec presets
16ded525 4152 */
16ded525
TI
4153static struct alc_config_preset alc880_presets[] = {
4154 [ALC880_3ST] = {
e9edcee0 4155 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4156 .init_verbs = { alc880_volume_init_verbs,
4157 alc880_pin_3stack_init_verbs },
16ded525 4158 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4159 .dac_nids = alc880_dac_nids,
16ded525
TI
4160 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4161 .channel_mode = alc880_threestack_modes,
4e195a7b 4162 .need_dac_fix = 1,
16ded525
TI
4163 .input_mux = &alc880_capture_source,
4164 },
4165 [ALC880_3ST_DIG] = {
e9edcee0 4166 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4167 .init_verbs = { alc880_volume_init_verbs,
4168 alc880_pin_3stack_init_verbs },
16ded525 4169 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4170 .dac_nids = alc880_dac_nids,
4171 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4172 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4173 .channel_mode = alc880_threestack_modes,
4e195a7b 4174 .need_dac_fix = 1,
16ded525
TI
4175 .input_mux = &alc880_capture_source,
4176 },
df694daa
KY
4177 [ALC880_TCL_S700] = {
4178 .mixers = { alc880_tcl_s700_mixer },
4179 .init_verbs = { alc880_volume_init_verbs,
4180 alc880_pin_tcl_S700_init_verbs,
4181 alc880_gpio2_init_verbs },
4182 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4183 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4184 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4185 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4186 .hp_nid = 0x03,
4187 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4188 .channel_mode = alc880_2_jack_modes,
4189 .input_mux = &alc880_capture_source,
4190 },
16ded525 4191 [ALC880_5ST] = {
f12ab1e0
TI
4192 .mixers = { alc880_three_stack_mixer,
4193 alc880_five_stack_mixer},
4194 .init_verbs = { alc880_volume_init_verbs,
4195 alc880_pin_5stack_init_verbs },
16ded525
TI
4196 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4197 .dac_nids = alc880_dac_nids,
16ded525
TI
4198 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4199 .channel_mode = alc880_fivestack_modes,
4200 .input_mux = &alc880_capture_source,
4201 },
4202 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4203 .mixers = { alc880_three_stack_mixer,
4204 alc880_five_stack_mixer },
4205 .init_verbs = { alc880_volume_init_verbs,
4206 alc880_pin_5stack_init_verbs },
16ded525
TI
4207 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4208 .dac_nids = alc880_dac_nids,
4209 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4210 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4211 .channel_mode = alc880_fivestack_modes,
4212 .input_mux = &alc880_capture_source,
4213 },
b6482d48
TI
4214 [ALC880_6ST] = {
4215 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4216 .init_verbs = { alc880_volume_init_verbs,
4217 alc880_pin_6stack_init_verbs },
b6482d48
TI
4218 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4219 .dac_nids = alc880_6st_dac_nids,
4220 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4221 .channel_mode = alc880_sixstack_modes,
4222 .input_mux = &alc880_6stack_capture_source,
4223 },
16ded525 4224 [ALC880_6ST_DIG] = {
e9edcee0 4225 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4226 .init_verbs = { alc880_volume_init_verbs,
4227 alc880_pin_6stack_init_verbs },
16ded525
TI
4228 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4229 .dac_nids = alc880_6st_dac_nids,
4230 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4231 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4232 .channel_mode = alc880_sixstack_modes,
4233 .input_mux = &alc880_6stack_capture_source,
4234 },
4235 [ALC880_W810] = {
e9edcee0 4236 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4237 .init_verbs = { alc880_volume_init_verbs,
4238 alc880_pin_w810_init_verbs,
b0af0de5 4239 alc880_gpio2_init_verbs },
16ded525
TI
4240 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4241 .dac_nids = alc880_w810_dac_nids,
4242 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4243 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4244 .channel_mode = alc880_w810_modes,
4245 .input_mux = &alc880_capture_source,
4246 },
4247 [ALC880_Z71V] = {
e9edcee0 4248 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4249 .init_verbs = { alc880_volume_init_verbs,
4250 alc880_pin_z71v_init_verbs },
16ded525
TI
4251 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4252 .dac_nids = alc880_z71v_dac_nids,
4253 .dig_out_nid = ALC880_DIGOUT_NID,
4254 .hp_nid = 0x03,
e9edcee0
TI
4255 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4256 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4257 .input_mux = &alc880_capture_source,
4258 },
4259 [ALC880_F1734] = {
e9edcee0 4260 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4261 .init_verbs = { alc880_volume_init_verbs,
4262 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4263 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4264 .dac_nids = alc880_f1734_dac_nids,
4265 .hp_nid = 0x02,
4266 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4267 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4268 .input_mux = &alc880_f1734_capture_source,
4269 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4270 .setup = alc880_uniwill_p53_setup,
4271 .init_hook = alc_automute_amp,
16ded525
TI
4272 },
4273 [ALC880_ASUS] = {
e9edcee0 4274 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4275 .init_verbs = { alc880_volume_init_verbs,
4276 alc880_pin_asus_init_verbs,
e9edcee0
TI
4277 alc880_gpio1_init_verbs },
4278 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4279 .dac_nids = alc880_asus_dac_nids,
4280 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4281 .channel_mode = alc880_asus_modes,
4e195a7b 4282 .need_dac_fix = 1,
16ded525
TI
4283 .input_mux = &alc880_capture_source,
4284 },
4285 [ALC880_ASUS_DIG] = {
e9edcee0 4286 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4287 .init_verbs = { alc880_volume_init_verbs,
4288 alc880_pin_asus_init_verbs,
e9edcee0
TI
4289 alc880_gpio1_init_verbs },
4290 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4291 .dac_nids = alc880_asus_dac_nids,
16ded525 4292 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4293 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4294 .channel_mode = alc880_asus_modes,
4e195a7b 4295 .need_dac_fix = 1,
16ded525
TI
4296 .input_mux = &alc880_capture_source,
4297 },
df694daa
KY
4298 [ALC880_ASUS_DIG2] = {
4299 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4300 .init_verbs = { alc880_volume_init_verbs,
4301 alc880_pin_asus_init_verbs,
df694daa
KY
4302 alc880_gpio2_init_verbs }, /* use GPIO2 */
4303 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4304 .dac_nids = alc880_asus_dac_nids,
4305 .dig_out_nid = ALC880_DIGOUT_NID,
4306 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4307 .channel_mode = alc880_asus_modes,
4e195a7b 4308 .need_dac_fix = 1,
df694daa
KY
4309 .input_mux = &alc880_capture_source,
4310 },
16ded525 4311 [ALC880_ASUS_W1V] = {
e9edcee0 4312 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4313 .init_verbs = { alc880_volume_init_verbs,
4314 alc880_pin_asus_init_verbs,
e9edcee0
TI
4315 alc880_gpio1_init_verbs },
4316 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4317 .dac_nids = alc880_asus_dac_nids,
16ded525 4318 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4319 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4320 .channel_mode = alc880_asus_modes,
4e195a7b 4321 .need_dac_fix = 1,
16ded525
TI
4322 .input_mux = &alc880_capture_source,
4323 },
4324 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4325 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4326 .init_verbs = { alc880_volume_init_verbs,
4327 alc880_pin_asus_init_verbs },
e9edcee0
TI
4328 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4329 .dac_nids = alc880_asus_dac_nids,
16ded525 4330 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4331 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4332 .channel_mode = alc880_asus_modes,
4e195a7b 4333 .need_dac_fix = 1,
16ded525
TI
4334 .input_mux = &alc880_capture_source,
4335 },
ccc656ce
KY
4336 [ALC880_UNIWILL] = {
4337 .mixers = { alc880_uniwill_mixer },
4338 .init_verbs = { alc880_volume_init_verbs,
4339 alc880_uniwill_init_verbs },
4340 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4341 .dac_nids = alc880_asus_dac_nids,
4342 .dig_out_nid = ALC880_DIGOUT_NID,
4343 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4344 .channel_mode = alc880_threestack_modes,
4345 .need_dac_fix = 1,
4346 .input_mux = &alc880_capture_source,
4347 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4348 .setup = alc880_uniwill_setup,
a9fd4f3f 4349 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4350 },
4351 [ALC880_UNIWILL_P53] = {
4352 .mixers = { alc880_uniwill_p53_mixer },
4353 .init_verbs = { alc880_volume_init_verbs,
4354 alc880_uniwill_p53_init_verbs },
4355 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4356 .dac_nids = alc880_asus_dac_nids,
4357 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4358 .channel_mode = alc880_threestack_modes,
4359 .input_mux = &alc880_capture_source,
4360 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4361 .setup = alc880_uniwill_p53_setup,
4362 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4363 },
4364 [ALC880_FUJITSU] = {
45bdd1c1 4365 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4366 .init_verbs = { alc880_volume_init_verbs,
4367 alc880_uniwill_p53_init_verbs,
4368 alc880_beep_init_verbs },
4369 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4370 .dac_nids = alc880_dac_nids,
d53d7d9e 4371 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4372 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4373 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4374 .input_mux = &alc880_capture_source,
4375 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4376 .setup = alc880_uniwill_p53_setup,
4377 .init_hook = alc_automute_amp,
ccc656ce 4378 },
df694daa
KY
4379 [ALC880_CLEVO] = {
4380 .mixers = { alc880_three_stack_mixer },
4381 .init_verbs = { alc880_volume_init_verbs,
4382 alc880_pin_clevo_init_verbs },
4383 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4384 .dac_nids = alc880_dac_nids,
4385 .hp_nid = 0x03,
4386 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4387 .channel_mode = alc880_threestack_modes,
4e195a7b 4388 .need_dac_fix = 1,
df694daa
KY
4389 .input_mux = &alc880_capture_source,
4390 },
ae6b813a
TI
4391 [ALC880_LG] = {
4392 .mixers = { alc880_lg_mixer },
4393 .init_verbs = { alc880_volume_init_verbs,
4394 alc880_lg_init_verbs },
4395 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4396 .dac_nids = alc880_lg_dac_nids,
4397 .dig_out_nid = ALC880_DIGOUT_NID,
4398 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4399 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4400 .need_dac_fix = 1,
ae6b813a 4401 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4402 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4403 .setup = alc880_lg_setup,
4404 .init_hook = alc_automute_amp,
cb53c626
TI
4405#ifdef CONFIG_SND_HDA_POWER_SAVE
4406 .loopbacks = alc880_lg_loopbacks,
4407#endif
ae6b813a 4408 },
d681518a
TI
4409 [ALC880_LG_LW] = {
4410 .mixers = { alc880_lg_lw_mixer },
4411 .init_verbs = { alc880_volume_init_verbs,
4412 alc880_lg_lw_init_verbs },
0a8c5da3 4413 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4414 .dac_nids = alc880_dac_nids,
4415 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4416 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4417 .channel_mode = alc880_lg_lw_modes,
d681518a 4418 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4419 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4420 .setup = alc880_lg_lw_setup,
4421 .init_hook = alc_automute_amp,
d681518a 4422 },
df99cd33
TI
4423 [ALC880_MEDION_RIM] = {
4424 .mixers = { alc880_medion_rim_mixer },
4425 .init_verbs = { alc880_volume_init_verbs,
4426 alc880_medion_rim_init_verbs,
4427 alc_gpio2_init_verbs },
4428 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4429 .dac_nids = alc880_dac_nids,
4430 .dig_out_nid = ALC880_DIGOUT_NID,
4431 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4432 .channel_mode = alc880_2_jack_modes,
4433 .input_mux = &alc880_medion_rim_capture_source,
4434 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4435 .setup = alc880_medion_rim_setup,
4436 .init_hook = alc880_medion_rim_automute,
df99cd33 4437 },
16ded525
TI
4438#ifdef CONFIG_SND_DEBUG
4439 [ALC880_TEST] = {
e9edcee0
TI
4440 .mixers = { alc880_test_mixer },
4441 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4442 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4443 .dac_nids = alc880_test_dac_nids,
4444 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4445 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4446 .channel_mode = alc880_test_modes,
4447 .input_mux = &alc880_test_capture_source,
4448 },
4449#endif
4450};
4451
e9edcee0
TI
4452/*
4453 * Automatic parse of I/O pins from the BIOS configuration
4454 */
4455
e9edcee0
TI
4456enum {
4457 ALC_CTL_WIDGET_VOL,
4458 ALC_CTL_WIDGET_MUTE,
4459 ALC_CTL_BIND_MUTE,
4460};
c8b6bf9b 4461static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4462 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4463 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4464 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4465};
4466
4467/* add dynamic controls */
f12ab1e0
TI
4468static int add_control(struct alc_spec *spec, int type, const char *name,
4469 unsigned long val)
e9edcee0 4470{
c8b6bf9b 4471 struct snd_kcontrol_new *knew;
e9edcee0 4472
603c4019
TI
4473 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4474 knew = snd_array_new(&spec->kctls);
4475 if (!knew)
4476 return -ENOMEM;
e9edcee0 4477 *knew = alc880_control_templates[type];
543537bd 4478 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4479 if (!knew->name)
e9edcee0 4480 return -ENOMEM;
4d02d1b6 4481 if (get_amp_nid_(val))
5e26dfd0 4482 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4483 knew->private_value = val;
e9edcee0
TI
4484 return 0;
4485}
4486
0afe5f89
TI
4487static int add_control_with_pfx(struct alc_spec *spec, int type,
4488 const char *pfx, const char *dir,
4489 const char *sfx, unsigned long val)
4490{
4491 char name[32];
4492 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4493 return add_control(spec, type, name, val);
4494}
4495
4496#define add_pb_vol_ctrl(spec, type, pfx, val) \
4497 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4498#define add_pb_sw_ctrl(spec, type, pfx, val) \
4499 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4500
e9edcee0
TI
4501#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4502#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4503#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4504#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4505#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4506#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4507#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4508#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4509#define ALC880_PIN_CD_NID 0x1c
4510
4511/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4512static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4513 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4514{
4515 hda_nid_t nid;
4516 int assigned[4];
4517 int i, j;
4518
4519 memset(assigned, 0, sizeof(assigned));
b0af0de5 4520 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4521
4522 /* check the pins hardwired to audio widget */
4523 for (i = 0; i < cfg->line_outs; i++) {
4524 nid = cfg->line_out_pins[i];
4525 if (alc880_is_fixed_pin(nid)) {
4526 int idx = alc880_fixed_pin_idx(nid);
5014f193 4527 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4528 assigned[idx] = 1;
4529 }
4530 }
4531 /* left pins can be connect to any audio widget */
4532 for (i = 0; i < cfg->line_outs; i++) {
4533 nid = cfg->line_out_pins[i];
4534 if (alc880_is_fixed_pin(nid))
4535 continue;
4536 /* search for an empty channel */
4537 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4538 if (!assigned[j]) {
4539 spec->multiout.dac_nids[i] =
4540 alc880_idx_to_dac(j);
e9edcee0
TI
4541 assigned[j] = 1;
4542 break;
4543 }
4544 }
4545 }
4546 spec->multiout.num_dacs = cfg->line_outs;
4547 return 0;
4548}
4549
4550/* add playback controls from the parsed DAC table */
df694daa
KY
4551static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4552 const struct auto_pin_cfg *cfg)
e9edcee0 4553{
f12ab1e0
TI
4554 static const char *chname[4] = {
4555 "Front", "Surround", NULL /*CLFE*/, "Side"
4556 };
e9edcee0
TI
4557 hda_nid_t nid;
4558 int i, err;
4559
4560 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4561 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4562 continue;
4563 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4564 if (i == 2) {
4565 /* Center/LFE */
0afe5f89
TI
4566 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4567 "Center",
f12ab1e0
TI
4568 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4569 HDA_OUTPUT));
4570 if (err < 0)
e9edcee0 4571 return err;
0afe5f89
TI
4572 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4573 "LFE",
f12ab1e0
TI
4574 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4575 HDA_OUTPUT));
4576 if (err < 0)
e9edcee0 4577 return err;
0afe5f89
TI
4578 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4579 "Center",
f12ab1e0
TI
4580 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4581 HDA_INPUT));
4582 if (err < 0)
e9edcee0 4583 return err;
0afe5f89
TI
4584 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4585 "LFE",
f12ab1e0
TI
4586 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4587 HDA_INPUT));
4588 if (err < 0)
e9edcee0
TI
4589 return err;
4590 } else {
cb162b6b
TI
4591 const char *pfx;
4592 if (cfg->line_outs == 1 &&
4593 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4594 pfx = "Speaker";
4595 else
4596 pfx = chname[i];
0afe5f89 4597 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4598 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4599 HDA_OUTPUT));
4600 if (err < 0)
e9edcee0 4601 return err;
0afe5f89 4602 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4603 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4604 HDA_INPUT));
4605 if (err < 0)
e9edcee0
TI
4606 return err;
4607 }
4608 }
e9edcee0
TI
4609 return 0;
4610}
4611
8d88bc3d
TI
4612/* add playback controls for speaker and HP outputs */
4613static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4614 const char *pfx)
e9edcee0
TI
4615{
4616 hda_nid_t nid;
4617 int err;
4618
f12ab1e0 4619 if (!pin)
e9edcee0
TI
4620 return 0;
4621
4622 if (alc880_is_fixed_pin(pin)) {
4623 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4624 /* specify the DAC as the extra output */
f12ab1e0 4625 if (!spec->multiout.hp_nid)
e9edcee0 4626 spec->multiout.hp_nid = nid;
82bc955f
TI
4627 else
4628 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4629 /* control HP volume/switch on the output mixer amp */
4630 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4631 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4632 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4633 if (err < 0)
e9edcee0 4634 return err;
0afe5f89 4635 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4636 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4637 if (err < 0)
e9edcee0
TI
4638 return err;
4639 } else if (alc880_is_multi_pin(pin)) {
4640 /* set manual connection */
e9edcee0 4641 /* we have only a switch on HP-out PIN */
0afe5f89 4642 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4643 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4644 if (err < 0)
e9edcee0
TI
4645 return err;
4646 }
4647 return 0;
4648}
4649
4650/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4651static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4652 const char *ctlname,
df694daa 4653 int idx, hda_nid_t mix_nid)
e9edcee0 4654{
df694daa 4655 int err;
e9edcee0 4656
0afe5f89 4657 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4658 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4659 if (err < 0)
e9edcee0 4660 return err;
0afe5f89 4661 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4662 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4663 if (err < 0)
e9edcee0
TI
4664 return err;
4665 return 0;
4666}
4667
05f5f477
TI
4668static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4669{
4670 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4671 return (pincap & AC_PINCAP_IN) != 0;
4672}
4673
e9edcee0 4674/* create playback/capture controls for input pins */
05f5f477
TI
4675static int alc_auto_create_input_ctls(struct hda_codec *codec,
4676 const struct auto_pin_cfg *cfg,
4677 hda_nid_t mixer,
4678 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4679{
05f5f477 4680 struct alc_spec *spec = codec->spec;
61b9b9b1 4681 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4682 int i, err, idx;
e9edcee0
TI
4683
4684 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4685 hda_nid_t pin;
4686
4687 pin = cfg->input_pins[i];
4688 if (!alc_is_input_pin(codec, pin))
4689 continue;
4690
4691 if (mixer) {
4692 idx = get_connection_index(codec, mixer, pin);
4693 if (idx >= 0) {
4694 err = new_analog_input(spec, pin,
4695 auto_pin_cfg_labels[i],
4696 idx, mixer);
4697 if (err < 0)
4698 return err;
4699 }
4700 }
4701
4702 if (!cap1)
4703 continue;
4704 idx = get_connection_index(codec, cap1, pin);
4705 if (idx < 0 && cap2)
4706 idx = get_connection_index(codec, cap2, pin);
4707 if (idx >= 0) {
f12ab1e0
TI
4708 imux->items[imux->num_items].label =
4709 auto_pin_cfg_labels[i];
05f5f477 4710 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4711 imux->num_items++;
4712 }
4713 }
4714 return 0;
4715}
4716
05f5f477
TI
4717static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4718 const struct auto_pin_cfg *cfg)
4719{
4720 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4721}
4722
f6c7e546
TI
4723static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4724 unsigned int pin_type)
4725{
4726 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4727 pin_type);
4728 /* unmute pin */
d260cdf6
TI
4729 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4730 AMP_OUT_UNMUTE);
f6c7e546
TI
4731}
4732
df694daa
KY
4733static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4734 hda_nid_t nid, int pin_type,
e9edcee0
TI
4735 int dac_idx)
4736{
f6c7e546 4737 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4738 /* need the manual connection? */
4739 if (alc880_is_multi_pin(nid)) {
4740 struct alc_spec *spec = codec->spec;
4741 int idx = alc880_multi_pin_idx(nid);
4742 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4743 AC_VERB_SET_CONNECT_SEL,
4744 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4745 }
4746}
4747
baba8ee9
TI
4748static int get_pin_type(int line_out_type)
4749{
4750 if (line_out_type == AUTO_PIN_HP_OUT)
4751 return PIN_HP;
4752 else
4753 return PIN_OUT;
4754}
4755
e9edcee0
TI
4756static void alc880_auto_init_multi_out(struct hda_codec *codec)
4757{
4758 struct alc_spec *spec = codec->spec;
4759 int i;
ea1fb29a 4760
e9edcee0
TI
4761 for (i = 0; i < spec->autocfg.line_outs; i++) {
4762 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4763 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4764 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4765 }
4766}
4767
8d88bc3d 4768static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4769{
4770 struct alc_spec *spec = codec->spec;
4771 hda_nid_t pin;
4772
82bc955f 4773 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4774 if (pin) /* connect to front */
4775 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4776 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4777 if (pin) /* connect to front */
4778 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4779}
4780
4781static void alc880_auto_init_analog_input(struct hda_codec *codec)
4782{
4783 struct alc_spec *spec = codec->spec;
4784 int i;
4785
4786 for (i = 0; i < AUTO_PIN_LAST; i++) {
4787 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 4788 if (alc_is_input_pin(codec, nid)) {
23f0c048 4789 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4790 if (nid != ALC880_PIN_CD_NID &&
4791 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4792 snd_hda_codec_write(codec, nid, 0,
4793 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4794 AMP_OUT_MUTE);
4795 }
4796 }
4797}
4798
4799/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4800/* return 1 if successful, 0 if the proper config is not found,
4801 * or a negative error code
4802 */
e9edcee0
TI
4803static int alc880_parse_auto_config(struct hda_codec *codec)
4804{
4805 struct alc_spec *spec = codec->spec;
6a05ac4a 4806 int i, err;
df694daa 4807 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4808
f12ab1e0
TI
4809 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4810 alc880_ignore);
4811 if (err < 0)
e9edcee0 4812 return err;
f12ab1e0 4813 if (!spec->autocfg.line_outs)
e9edcee0 4814 return 0; /* can't find valid BIOS pin config */
df694daa 4815
f12ab1e0
TI
4816 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4817 if (err < 0)
4818 return err;
4819 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4820 if (err < 0)
4821 return err;
4822 err = alc880_auto_create_extra_out(spec,
4823 spec->autocfg.speaker_pins[0],
4824 "Speaker");
4825 if (err < 0)
4826 return err;
4827 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4828 "Headphone");
4829 if (err < 0)
4830 return err;
05f5f477 4831 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 4832 if (err < 0)
e9edcee0
TI
4833 return err;
4834
4835 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4836
6a05ac4a
TI
4837 /* check multiple SPDIF-out (for recent codecs) */
4838 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4839 hda_nid_t dig_nid;
4840 err = snd_hda_get_connections(codec,
4841 spec->autocfg.dig_out_pins[i],
4842 &dig_nid, 1);
4843 if (err < 0)
4844 continue;
4845 if (!i)
4846 spec->multiout.dig_out_nid = dig_nid;
4847 else {
4848 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 4849 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
6a05ac4a 4850 break;
71121d9f 4851 spec->slave_dig_outs[i - 1] = dig_nid;
6a05ac4a
TI
4852 }
4853 }
e9edcee0
TI
4854 if (spec->autocfg.dig_in_pin)
4855 spec->dig_in_nid = ALC880_DIGIN_NID;
4856
603c4019 4857 if (spec->kctls.list)
d88897ea 4858 add_mixer(spec, spec->kctls.list);
e9edcee0 4859
d88897ea 4860 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4861
a1e8d2da 4862 spec->num_mux_defs = 1;
61b9b9b1 4863 spec->input_mux = &spec->private_imux[0];
e9edcee0 4864
6227cdce 4865 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 4866
e9edcee0
TI
4867 return 1;
4868}
4869
ae6b813a
TI
4870/* additional initialization for auto-configuration model */
4871static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4872{
f6c7e546 4873 struct alc_spec *spec = codec->spec;
e9edcee0 4874 alc880_auto_init_multi_out(codec);
8d88bc3d 4875 alc880_auto_init_extra_out(codec);
e9edcee0 4876 alc880_auto_init_analog_input(codec);
f6c7e546 4877 if (spec->unsol_event)
7fb0d78f 4878 alc_inithook(codec);
e9edcee0
TI
4879}
4880
b59bdf3b
TI
4881/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4882 * one of two digital mic pins, e.g. on ALC272
4883 */
4884static void fixup_automic_adc(struct hda_codec *codec)
4885{
4886 struct alc_spec *spec = codec->spec;
4887 int i;
4888
4889 for (i = 0; i < spec->num_adc_nids; i++) {
4890 hda_nid_t cap = spec->capsrc_nids ?
4891 spec->capsrc_nids[i] : spec->adc_nids[i];
4892 int iidx, eidx;
4893
4894 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4895 if (iidx < 0)
4896 continue;
4897 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4898 if (eidx < 0)
4899 continue;
4900 spec->int_mic.mux_idx = iidx;
4901 spec->ext_mic.mux_idx = eidx;
4902 if (spec->capsrc_nids)
4903 spec->capsrc_nids += i;
4904 spec->adc_nids += i;
4905 spec->num_adc_nids = 1;
4906 return;
4907 }
4908 snd_printd(KERN_INFO "hda_codec: %s: "
4909 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4910 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4911 spec->auto_mic = 0; /* disable auto-mic to be sure */
4912}
4913
eaa9b3a7
TI
4914/* choose the ADC/MUX containing the input pin and initialize the setup */
4915static void fixup_single_adc(struct hda_codec *codec)
4916{
4917 struct alc_spec *spec = codec->spec;
d2db09b8 4918 hda_nid_t pin = 0;
eaa9b3a7
TI
4919 int i;
4920
4921 /* search for the input pin; there must be only one */
4922 for (i = 0; i < AUTO_PIN_LAST; i++) {
4923 if (spec->autocfg.input_pins[i]) {
4924 pin = spec->autocfg.input_pins[i];
4925 break;
4926 }
4927 }
4928 if (!pin)
4929 return;
4930
4931 /* set the default connection to that pin */
4932 for (i = 0; i < spec->num_adc_nids; i++) {
4933 hda_nid_t cap = spec->capsrc_nids ?
4934 spec->capsrc_nids[i] : spec->adc_nids[i];
4935 int idx;
4936
4937 idx = get_connection_index(codec, cap, pin);
4938 if (idx < 0)
4939 continue;
4940 /* use only this ADC */
4941 if (spec->capsrc_nids)
4942 spec->capsrc_nids += i;
4943 spec->adc_nids += i;
4944 spec->num_adc_nids = 1;
4945 /* select or unmute this route */
4946 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
4947 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
4948 HDA_AMP_MUTE, 0);
4949 } else {
4950 snd_hda_codec_write_cache(codec, cap, 0,
4951 AC_VERB_SET_CONNECT_SEL, idx);
4952 }
4953 return;
4954 }
4955}
4956
b59bdf3b 4957static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 4958{
b59bdf3b 4959 struct alc_spec *spec = codec->spec;
a23b688f
TI
4960 static struct snd_kcontrol_new *caps[2][3] = {
4961 { alc_capture_mixer_nosrc1,
4962 alc_capture_mixer_nosrc2,
4963 alc_capture_mixer_nosrc3 },
4964 { alc_capture_mixer1,
4965 alc_capture_mixer2,
4966 alc_capture_mixer3 },
f9e336f6 4967 };
a23b688f 4968 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7
TI
4969 int mux = 0;
4970 if (spec->auto_mic)
b59bdf3b 4971 fixup_automic_adc(codec);
eaa9b3a7
TI
4972 else if (spec->input_mux) {
4973 if (spec->input_mux->num_items > 1)
4974 mux = 1;
4975 else if (spec->input_mux->num_items == 1)
4976 fixup_single_adc(codec);
4977 }
a23b688f
TI
4978 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4979 }
f9e336f6
TI
4980}
4981
67d634c0 4982#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
4983#define set_beep_amp(spec, nid, idx, dir) \
4984 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
67d634c0
TI
4985#else
4986#define set_beep_amp(spec, nid, idx, dir) /* NOP */
4987#endif
45bdd1c1
TI
4988
4989/*
4990 * OK, here we have finally the patch for ALC880
4991 */
4992
1da177e4
LT
4993static int patch_alc880(struct hda_codec *codec)
4994{
4995 struct alc_spec *spec;
4996 int board_config;
df694daa 4997 int err;
1da177e4 4998
e560d8d8 4999 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5000 if (spec == NULL)
5001 return -ENOMEM;
5002
5003 codec->spec = spec;
5004
f5fcc13c
TI
5005 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5006 alc880_models,
5007 alc880_cfg_tbl);
5008 if (board_config < 0) {
9a11f1aa
TI
5009 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5010 codec->chip_name);
e9edcee0 5011 board_config = ALC880_AUTO;
1da177e4 5012 }
1da177e4 5013
e9edcee0
TI
5014 if (board_config == ALC880_AUTO) {
5015 /* automatic parse from the BIOS config */
5016 err = alc880_parse_auto_config(codec);
5017 if (err < 0) {
5018 alc_free(codec);
5019 return err;
f12ab1e0 5020 } else if (!err) {
9c7f852e
TI
5021 printk(KERN_INFO
5022 "hda_codec: Cannot set up configuration "
5023 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5024 board_config = ALC880_3ST;
5025 }
1da177e4
LT
5026 }
5027
680cd536
KK
5028 err = snd_hda_attach_beep_device(codec, 0x1);
5029 if (err < 0) {
5030 alc_free(codec);
5031 return err;
5032 }
5033
df694daa 5034 if (board_config != ALC880_AUTO)
e9c364c0 5035 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5036
1da177e4
LT
5037 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5038 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5039 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5040
1da177e4
LT
5041 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5042 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5043
f12ab1e0 5044 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5045 /* check whether NID 0x07 is valid */
54d17403 5046 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5047 /* get type */
a22d543a 5048 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5049 if (wcap != AC_WID_AUD_IN) {
5050 spec->adc_nids = alc880_adc_nids_alt;
5051 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5052 } else {
5053 spec->adc_nids = alc880_adc_nids;
5054 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5055 }
5056 }
b59bdf3b 5057 set_capture_mixer(codec);
45bdd1c1 5058 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5059
2134ea4f
TI
5060 spec->vmaster_nid = 0x0c;
5061
1da177e4 5062 codec->patch_ops = alc_patch_ops;
e9edcee0 5063 if (board_config == ALC880_AUTO)
ae6b813a 5064 spec->init_hook = alc880_auto_init;
cb53c626
TI
5065#ifdef CONFIG_SND_HDA_POWER_SAVE
5066 if (!spec->loopback.amplist)
5067 spec->loopback.amplist = alc880_loopbacks;
5068#endif
1da177e4
LT
5069
5070 return 0;
5071}
5072
e9edcee0 5073
1da177e4
LT
5074/*
5075 * ALC260 support
5076 */
5077
e9edcee0
TI
5078static hda_nid_t alc260_dac_nids[1] = {
5079 /* front */
5080 0x02,
5081};
5082
5083static hda_nid_t alc260_adc_nids[1] = {
5084 /* ADC0 */
5085 0x04,
5086};
5087
df694daa 5088static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5089 /* ADC1 */
5090 0x05,
5091};
5092
d57fdac0
JW
5093/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5094 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5095 */
5096static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5097 /* ADC0, ADC1 */
5098 0x04, 0x05
5099};
5100
e9edcee0
TI
5101#define ALC260_DIGOUT_NID 0x03
5102#define ALC260_DIGIN_NID 0x06
5103
5104static struct hda_input_mux alc260_capture_source = {
5105 .num_items = 4,
5106 .items = {
5107 { "Mic", 0x0 },
5108 { "Front Mic", 0x1 },
5109 { "Line", 0x2 },
5110 { "CD", 0x4 },
5111 },
5112};
5113
17e7aec6 5114/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5115 * headphone jack and the internal CD lines since these are the only pins at
5116 * which audio can appear. For flexibility, also allow the option of
5117 * recording the mixer output on the second ADC (ADC0 doesn't have a
5118 * connection to the mixer output).
a9430dd8 5119 */
a1e8d2da
JW
5120static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5121 {
5122 .num_items = 3,
5123 .items = {
5124 { "Mic/Line", 0x0 },
5125 { "CD", 0x4 },
5126 { "Headphone", 0x2 },
5127 },
a9430dd8 5128 },
a1e8d2da
JW
5129 {
5130 .num_items = 4,
5131 .items = {
5132 { "Mic/Line", 0x0 },
5133 { "CD", 0x4 },
5134 { "Headphone", 0x2 },
5135 { "Mixer", 0x5 },
5136 },
5137 },
5138
a9430dd8
JW
5139};
5140
a1e8d2da
JW
5141/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5142 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5143 */
a1e8d2da
JW
5144static struct hda_input_mux alc260_acer_capture_sources[2] = {
5145 {
5146 .num_items = 4,
5147 .items = {
5148 { "Mic", 0x0 },
5149 { "Line", 0x2 },
5150 { "CD", 0x4 },
5151 { "Headphone", 0x5 },
5152 },
5153 },
5154 {
5155 .num_items = 5,
5156 .items = {
5157 { "Mic", 0x0 },
5158 { "Line", 0x2 },
5159 { "CD", 0x4 },
5160 { "Headphone", 0x6 },
5161 { "Mixer", 0x5 },
5162 },
0bfc90e9
JW
5163 },
5164};
cc959489
MS
5165
5166/* Maxdata Favorit 100XS */
5167static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5168 {
5169 .num_items = 2,
5170 .items = {
5171 { "Line/Mic", 0x0 },
5172 { "CD", 0x4 },
5173 },
5174 },
5175 {
5176 .num_items = 3,
5177 .items = {
5178 { "Line/Mic", 0x0 },
5179 { "CD", 0x4 },
5180 { "Mixer", 0x5 },
5181 },
5182 },
5183};
5184
1da177e4
LT
5185/*
5186 * This is just place-holder, so there's something for alc_build_pcms to look
5187 * at when it calculates the maximum number of channels. ALC260 has no mixer
5188 * element which allows changing the channel mode, so the verb list is
5189 * never used.
5190 */
d2a6d7dc 5191static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5192 { 2, NULL },
5193};
5194
df694daa
KY
5195
5196/* Mixer combinations
5197 *
5198 * basic: base_output + input + pc_beep + capture
5199 * HP: base_output + input + capture_alt
5200 * HP_3013: hp_3013 + input + capture
5201 * fujitsu: fujitsu + capture
0bfc90e9 5202 * acer: acer + capture
df694daa
KY
5203 */
5204
5205static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5206 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5207 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5209 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5210 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5211 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5212 { } /* end */
f12ab1e0 5213};
1da177e4 5214
df694daa 5215static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5216 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5217 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5218 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5219 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5221 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5223 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5224 { } /* end */
5225};
5226
bec15c3a
TI
5227/* update HP, line and mono out pins according to the master switch */
5228static void alc260_hp_master_update(struct hda_codec *codec,
5229 hda_nid_t hp, hda_nid_t line,
5230 hda_nid_t mono)
5231{
5232 struct alc_spec *spec = codec->spec;
5233 unsigned int val = spec->master_sw ? PIN_HP : 0;
5234 /* change HP and line-out pins */
30cde0aa 5235 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5236 val);
30cde0aa 5237 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5238 val);
5239 /* mono (speaker) depending on the HP jack sense */
5240 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5241 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5242 val);
5243}
5244
5245static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5246 struct snd_ctl_elem_value *ucontrol)
5247{
5248 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5249 struct alc_spec *spec = codec->spec;
5250 *ucontrol->value.integer.value = spec->master_sw;
5251 return 0;
5252}
5253
5254static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5255 struct snd_ctl_elem_value *ucontrol)
5256{
5257 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5258 struct alc_spec *spec = codec->spec;
5259 int val = !!*ucontrol->value.integer.value;
5260 hda_nid_t hp, line, mono;
5261
5262 if (val == spec->master_sw)
5263 return 0;
5264 spec->master_sw = val;
5265 hp = (kcontrol->private_value >> 16) & 0xff;
5266 line = (kcontrol->private_value >> 8) & 0xff;
5267 mono = kcontrol->private_value & 0xff;
5268 alc260_hp_master_update(codec, hp, line, mono);
5269 return 1;
5270}
5271
5272static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5273 {
5274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5275 .name = "Master Playback Switch",
5b0cb1d8 5276 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5277 .info = snd_ctl_boolean_mono_info,
5278 .get = alc260_hp_master_sw_get,
5279 .put = alc260_hp_master_sw_put,
5280 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5281 },
5282 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5283 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5284 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5285 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5286 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5287 HDA_OUTPUT),
5288 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5289 { } /* end */
5290};
5291
5292static struct hda_verb alc260_hp_unsol_verbs[] = {
5293 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5294 {},
5295};
5296
5297static void alc260_hp_automute(struct hda_codec *codec)
5298{
5299 struct alc_spec *spec = codec->spec;
bec15c3a 5300
864f92be 5301 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5302 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5303}
5304
5305static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5306{
5307 if ((res >> 26) == ALC880_HP_EVENT)
5308 alc260_hp_automute(codec);
5309}
5310
df694daa 5311static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5312 {
5313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5314 .name = "Master Playback Switch",
5b0cb1d8 5315 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5316 .info = snd_ctl_boolean_mono_info,
5317 .get = alc260_hp_master_sw_get,
5318 .put = alc260_hp_master_sw_put,
30cde0aa 5319 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5320 },
df694daa
KY
5321 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5322 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5323 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5324 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5325 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5327 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5328 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5329 { } /* end */
5330};
5331
3f878308
KY
5332static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5333 .ops = &snd_hda_bind_vol,
5334 .values = {
5335 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5336 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5337 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5338 0
5339 },
5340};
5341
5342static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5343 .ops = &snd_hda_bind_sw,
5344 .values = {
5345 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5346 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5347 0
5348 },
5349};
5350
5351static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5352 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5353 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5354 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5355 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5356 { } /* end */
5357};
5358
bec15c3a
TI
5359static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5360 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5361 {},
5362};
5363
5364static void alc260_hp_3013_automute(struct hda_codec *codec)
5365{
5366 struct alc_spec *spec = codec->spec;
bec15c3a 5367
864f92be 5368 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5369 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5370}
5371
5372static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5373 unsigned int res)
5374{
5375 if ((res >> 26) == ALC880_HP_EVENT)
5376 alc260_hp_3013_automute(codec);
5377}
5378
3f878308
KY
5379static void alc260_hp_3012_automute(struct hda_codec *codec)
5380{
864f92be 5381 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5382
3f878308
KY
5383 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5384 bits);
5385 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5386 bits);
5387 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5388 bits);
5389}
5390
5391static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5392 unsigned int res)
5393{
5394 if ((res >> 26) == ALC880_HP_EVENT)
5395 alc260_hp_3012_automute(codec);
5396}
5397
5398/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5399 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5400 */
c8b6bf9b 5401static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5402 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5403 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5404 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5405 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5406 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5407 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5408 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5409 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5410 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5411 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5412 { } /* end */
5413};
5414
a1e8d2da
JW
5415/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5416 * versions of the ALC260 don't act on requests to enable mic bias from NID
5417 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5418 * datasheet doesn't mention this restriction. At this stage it's not clear
5419 * whether this behaviour is intentional or is a hardware bug in chip
5420 * revisions available in early 2006. Therefore for now allow the
5421 * "Headphone Jack Mode" control to span all choices, but if it turns out
5422 * that the lack of mic bias for this NID is intentional we could change the
5423 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5424 *
5425 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5426 * don't appear to make the mic bias available from the "line" jack, even
5427 * though the NID used for this jack (0x14) can supply it. The theory is
5428 * that perhaps Acer have included blocking capacitors between the ALC260
5429 * and the output jack. If this turns out to be the case for all such
5430 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5431 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5432 *
5433 * The C20x Tablet series have a mono internal speaker which is controlled
5434 * via the chip's Mono sum widget and pin complex, so include the necessary
5435 * controls for such models. On models without a "mono speaker" the control
5436 * won't do anything.
a1e8d2da 5437 */
0bfc90e9
JW
5438static struct snd_kcontrol_new alc260_acer_mixer[] = {
5439 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5440 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5441 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5442 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5443 HDA_OUTPUT),
31bffaa9 5444 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5445 HDA_INPUT),
0bfc90e9
JW
5446 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5447 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5448 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5449 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5450 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5451 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5452 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5453 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5454 { } /* end */
5455};
5456
cc959489
MS
5457/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5458 */
5459static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5460 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5461 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5462 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5463 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5464 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5465 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5466 { } /* end */
5467};
5468
bc9f98a9
KY
5469/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5470 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5471 */
5472static struct snd_kcontrol_new alc260_will_mixer[] = {
5473 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5474 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5475 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5476 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5477 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5478 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5479 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5480 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5481 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5482 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5483 { } /* end */
5484};
5485
5486/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5487 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5488 */
5489static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5490 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5491 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5493 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5494 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5495 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5496 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5497 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5498 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5499 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5500 { } /* end */
5501};
5502
df694daa
KY
5503/*
5504 * initialization verbs
5505 */
1da177e4
LT
5506static struct hda_verb alc260_init_verbs[] = {
5507 /* Line In pin widget for input */
05acb863 5508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5509 /* CD pin widget for input */
05acb863 5510 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5511 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5512 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5513 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5514 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5515 /* LINE-2 is used for line-out in rear */
05acb863 5516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5517 /* select line-out */
fd56f2db 5518 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5519 /* LINE-OUT pin */
05acb863 5520 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5521 /* enable HP */
05acb863 5522 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5523 /* enable Mono */
05acb863
TI
5524 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5525 /* mute capture amp left and right */
16ded525 5526 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5527 /* set connection select to line in (default select for this ADC) */
5528 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5529 /* mute capture amp left and right */
5530 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5531 /* set connection select to line in (default select for this ADC) */
5532 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5533 /* set vol=0 Line-Out mixer amp left and right */
5534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5535 /* unmute pin widget amp left and right (no gain on this amp) */
5536 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5537 /* set vol=0 HP mixer amp left and right */
5538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5539 /* unmute pin widget amp left and right (no gain on this amp) */
5540 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5541 /* set vol=0 Mono mixer amp left and right */
5542 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5543 /* unmute pin widget amp left and right (no gain on this amp) */
5544 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5545 /* unmute LINE-2 out pin */
5546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5547 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5548 * Line In 2 = 0x03
5549 */
cb53c626
TI
5550 /* mute analog inputs */
5551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5554 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5555 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5556 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5557 /* mute Front out path */
5558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5560 /* mute Headphone out path */
5561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5562 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5563 /* mute Mono out path */
5564 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5565 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5566 { }
5567};
5568
474167d6 5569#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5570static struct hda_verb alc260_hp_init_verbs[] = {
5571 /* Headphone and output */
5572 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5573 /* mono output */
5574 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5575 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5576 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5577 /* Mic2 (front panel) pin widget for input and vref at 80% */
5578 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5579 /* Line In pin widget for input */
5580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5581 /* Line-2 pin widget for output */
5582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5583 /* CD pin widget for input */
5584 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5585 /* unmute amp left and right */
5586 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5587 /* set connection select to line in (default select for this ADC) */
5588 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5589 /* unmute Line-Out mixer amp left and right (volume = 0) */
5590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5591 /* mute pin widget amp left and right (no gain on this amp) */
5592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5593 /* unmute HP mixer amp left and right (volume = 0) */
5594 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5595 /* mute pin widget amp left and right (no gain on this amp) */
5596 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5597 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5598 * Line In 2 = 0x03
5599 */
cb53c626
TI
5600 /* mute analog inputs */
5601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5603 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5604 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5605 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5606 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5607 /* Unmute Front out path */
5608 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5609 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5610 /* Unmute Headphone out path */
5611 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5612 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5613 /* Unmute Mono out path */
5614 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5615 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5616 { }
5617};
474167d6 5618#endif
df694daa
KY
5619
5620static struct hda_verb alc260_hp_3013_init_verbs[] = {
5621 /* Line out and output */
5622 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5623 /* mono output */
5624 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5625 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5626 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5627 /* Mic2 (front panel) pin widget for input and vref at 80% */
5628 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5629 /* Line In pin widget for input */
5630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5631 /* Headphone pin widget for output */
5632 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5633 /* CD pin widget for input */
5634 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5635 /* unmute amp left and right */
5636 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5637 /* set connection select to line in (default select for this ADC) */
5638 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5639 /* unmute Line-Out mixer amp left and right (volume = 0) */
5640 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5641 /* mute pin widget amp left and right (no gain on this amp) */
5642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5643 /* unmute HP mixer amp left and right (volume = 0) */
5644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5645 /* mute pin widget amp left and right (no gain on this amp) */
5646 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5647 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5648 * Line In 2 = 0x03
5649 */
cb53c626
TI
5650 /* mute analog inputs */
5651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5653 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5656 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5657 /* Unmute Front out path */
5658 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5659 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5660 /* Unmute Headphone out path */
5661 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5663 /* Unmute Mono out path */
5664 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5665 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5666 { }
5667};
5668
a9430dd8 5669/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5670 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5671 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5672 */
5673static struct hda_verb alc260_fujitsu_init_verbs[] = {
5674 /* Disable all GPIOs */
5675 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5676 /* Internal speaker is connected to headphone pin */
5677 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5678 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5679 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5680 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5681 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5682 /* Ensure all other unused pins are disabled and muted. */
5683 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5685 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5686 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5687 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5688 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5691
5692 /* Disable digital (SPDIF) pins */
5693 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5694 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5695
ea1fb29a 5696 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5697 * when acting as an output.
5698 */
5699 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5700
f7ace40d 5701 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5702 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5704 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5706 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5708 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5709 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5710 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5711
f7ace40d
JW
5712 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5713 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5714 /* Unmute Line1 pin widget output buffer since it starts as an output.
5715 * If the pin mode is changed by the user the pin mode control will
5716 * take care of enabling the pin's input/output buffers as needed.
5717 * Therefore there's no need to enable the input buffer at this
5718 * stage.
cdcd9268 5719 */
f7ace40d 5720 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5721 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5722 * mixer ctrl)
5723 */
f7ace40d
JW
5724 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5725
5726 /* Mute capture amp left and right */
5727 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5728 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5729 * in (on mic1 pin)
5730 */
5731 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5732
5733 /* Do the same for the second ADC: mute capture input amp and
5734 * set ADC connection to line in (on mic1 pin)
5735 */
5736 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5737 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5738
5739 /* Mute all inputs to mixer widget (even unconnected ones) */
5740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5748
5749 { }
a9430dd8
JW
5750};
5751
0bfc90e9
JW
5752/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5753 * similar laptops (adapted from Fujitsu init verbs).
5754 */
5755static struct hda_verb alc260_acer_init_verbs[] = {
5756 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5757 * the headphone jack. Turn this on and rely on the standard mute
5758 * methods whenever the user wants to turn these outputs off.
5759 */
5760 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5761 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5762 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5763 /* Internal speaker/Headphone jack is connected to Line-out pin */
5764 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5765 /* Internal microphone/Mic jack is connected to Mic1 pin */
5766 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5767 /* Line In jack is connected to Line1 pin */
5768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5769 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5770 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5771 /* Ensure all other unused pins are disabled and muted. */
5772 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5773 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5774 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5775 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5778 /* Disable digital (SPDIF) pins */
5779 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5780 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5781
ea1fb29a 5782 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5783 * bus when acting as outputs.
5784 */
5785 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5786 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5787
5788 /* Start with output sum widgets muted and their output gains at min */
5789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5791 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5798
f12ab1e0
TI
5799 /* Unmute Line-out pin widget amp left and right
5800 * (no equiv mixer ctrl)
5801 */
0bfc90e9 5802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5803 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5804 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5805 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5806 * inputs. If the pin mode is changed by the user the pin mode control
5807 * will take care of enabling the pin's input/output buffers as needed.
5808 * Therefore there's no need to enable the input buffer at this
5809 * stage.
5810 */
5811 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5813
5814 /* Mute capture amp left and right */
5815 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5816 /* Set ADC connection select to match default mixer setting - mic
5817 * (on mic1 pin)
5818 */
5819 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5820
5821 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5822 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5823 */
5824 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5825 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5826
5827 /* Mute all inputs to mixer widget (even unconnected ones) */
5828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5833 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5834 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5835 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5836
5837 { }
5838};
5839
cc959489
MS
5840/* Initialisation sequence for Maxdata Favorit 100XS
5841 * (adapted from Acer init verbs).
5842 */
5843static struct hda_verb alc260_favorit100_init_verbs[] = {
5844 /* GPIO 0 enables the output jack.
5845 * Turn this on and rely on the standard mute
5846 * methods whenever the user wants to turn these outputs off.
5847 */
5848 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5849 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5850 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5851 /* Line/Mic input jack is connected to Mic1 pin */
5852 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5853 /* Ensure all other unused pins are disabled and muted. */
5854 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5855 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5856 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5857 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5858 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5859 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5863 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5864 /* Disable digital (SPDIF) pins */
5865 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5866 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5867
5868 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5869 * bus when acting as outputs.
5870 */
5871 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5872 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5873
5874 /* Start with output sum widgets muted and their output gains at min */
5875 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5876 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5877 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5878 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5879 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5880 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5881 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5882 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5883 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5884
5885 /* Unmute Line-out pin widget amp left and right
5886 * (no equiv mixer ctrl)
5887 */
5888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5889 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5890 * inputs. If the pin mode is changed by the user the pin mode control
5891 * will take care of enabling the pin's input/output buffers as needed.
5892 * Therefore there's no need to enable the input buffer at this
5893 * stage.
5894 */
5895 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5896
5897 /* Mute capture amp left and right */
5898 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5899 /* Set ADC connection select to match default mixer setting - mic
5900 * (on mic1 pin)
5901 */
5902 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5903
5904 /* Do similar with the second ADC: mute capture input amp and
5905 * set ADC connection to mic to match ALSA's default state.
5906 */
5907 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5908 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5909
5910 /* Mute all inputs to mixer widget (even unconnected ones) */
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5914 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5919
5920 { }
5921};
5922
bc9f98a9
KY
5923static struct hda_verb alc260_will_verbs[] = {
5924 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5925 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5926 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5927 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5928 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5929 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5930 {}
5931};
5932
5933static struct hda_verb alc260_replacer_672v_verbs[] = {
5934 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5935 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5936 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5937
5938 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5939 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5940 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5941
5942 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5943 {}
5944};
5945
5946/* toggle speaker-output according to the hp-jack state */
5947static void alc260_replacer_672v_automute(struct hda_codec *codec)
5948{
5949 unsigned int present;
5950
5951 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 5952 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 5953 if (present) {
82beb8fd
TI
5954 snd_hda_codec_write_cache(codec, 0x01, 0,
5955 AC_VERB_SET_GPIO_DATA, 1);
5956 snd_hda_codec_write_cache(codec, 0x0f, 0,
5957 AC_VERB_SET_PIN_WIDGET_CONTROL,
5958 PIN_HP);
bc9f98a9 5959 } else {
82beb8fd
TI
5960 snd_hda_codec_write_cache(codec, 0x01, 0,
5961 AC_VERB_SET_GPIO_DATA, 0);
5962 snd_hda_codec_write_cache(codec, 0x0f, 0,
5963 AC_VERB_SET_PIN_WIDGET_CONTROL,
5964 PIN_OUT);
bc9f98a9
KY
5965 }
5966}
5967
5968static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5969 unsigned int res)
5970{
5971 if ((res >> 26) == ALC880_HP_EVENT)
5972 alc260_replacer_672v_automute(codec);
5973}
5974
3f878308
KY
5975static struct hda_verb alc260_hp_dc7600_verbs[] = {
5976 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5978 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5979 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5980 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5982 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5983 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5984 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5985 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5986 {}
5987};
5988
7cf51e48
JW
5989/* Test configuration for debugging, modelled after the ALC880 test
5990 * configuration.
5991 */
5992#ifdef CONFIG_SND_DEBUG
5993static hda_nid_t alc260_test_dac_nids[1] = {
5994 0x02,
5995};
5996static hda_nid_t alc260_test_adc_nids[2] = {
5997 0x04, 0x05,
5998};
a1e8d2da 5999/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6000 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6001 * is NID 0x04.
17e7aec6 6002 */
a1e8d2da
JW
6003static struct hda_input_mux alc260_test_capture_sources[2] = {
6004 {
6005 .num_items = 7,
6006 .items = {
6007 { "MIC1 pin", 0x0 },
6008 { "MIC2 pin", 0x1 },
6009 { "LINE1 pin", 0x2 },
6010 { "LINE2 pin", 0x3 },
6011 { "CD pin", 0x4 },
6012 { "LINE-OUT pin", 0x5 },
6013 { "HP-OUT pin", 0x6 },
6014 },
6015 },
6016 {
6017 .num_items = 8,
6018 .items = {
6019 { "MIC1 pin", 0x0 },
6020 { "MIC2 pin", 0x1 },
6021 { "LINE1 pin", 0x2 },
6022 { "LINE2 pin", 0x3 },
6023 { "CD pin", 0x4 },
6024 { "Mixer", 0x5 },
6025 { "LINE-OUT pin", 0x6 },
6026 { "HP-OUT pin", 0x7 },
6027 },
7cf51e48
JW
6028 },
6029};
6030static struct snd_kcontrol_new alc260_test_mixer[] = {
6031 /* Output driver widgets */
6032 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6033 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6034 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6035 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6036 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6037 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6038
a1e8d2da
JW
6039 /* Modes for retasking pin widgets
6040 * Note: the ALC260 doesn't seem to act on requests to enable mic
6041 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6042 * mention this restriction. At this stage it's not clear whether
6043 * this behaviour is intentional or is a hardware bug in chip
6044 * revisions available at least up until early 2006. Therefore for
6045 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6046 * choices, but if it turns out that the lack of mic bias for these
6047 * NIDs is intentional we could change their modes from
6048 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6049 */
7cf51e48
JW
6050 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6051 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6052 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6053 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6054 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6055 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6056
6057 /* Loopback mixer controls */
6058 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6059 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6060 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6061 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6062 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6063 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6064 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6065 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6066 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6067 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6068 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6069 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6070 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6071 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6072
6073 /* Controls for GPIO pins, assuming they are configured as outputs */
6074 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6075 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6076 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6077 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6078
92621f13
JW
6079 /* Switches to allow the digital IO pins to be enabled. The datasheet
6080 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6081 * make this output available should provide clarification.
92621f13
JW
6082 */
6083 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6084 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6085
f8225f6d
JW
6086 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6087 * this output to turn on an external amplifier.
6088 */
6089 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6090 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6091
7cf51e48
JW
6092 { } /* end */
6093};
6094static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6095 /* Enable all GPIOs as outputs with an initial value of 0 */
6096 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6097 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6098 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6099
7cf51e48
JW
6100 /* Enable retasking pins as output, initially without power amp */
6101 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6102 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6103 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6105 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6106 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6107
92621f13
JW
6108 /* Disable digital (SPDIF) pins initially, but users can enable
6109 * them via a mixer switch. In the case of SPDIF-out, this initverb
6110 * payload also sets the generation to 0, output to be in "consumer"
6111 * PCM format, copyright asserted, no pre-emphasis and no validity
6112 * control.
6113 */
7cf51e48
JW
6114 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6115 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6116
ea1fb29a 6117 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6118 * OUT1 sum bus when acting as an output.
6119 */
6120 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6121 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6122 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6123 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6124
6125 /* Start with output sum widgets muted and their output gains at min */
6126 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6127 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6128 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6129 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6130 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6131 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6132 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6133 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6134 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6135
cdcd9268
JW
6136 /* Unmute retasking pin widget output buffers since the default
6137 * state appears to be output. As the pin mode is changed by the
6138 * user the pin mode control will take care of enabling the pin's
6139 * input/output buffers as needed.
6140 */
7cf51e48
JW
6141 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6143 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6145 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6146 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6147 /* Also unmute the mono-out pin widget */
6148 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6149
7cf51e48
JW
6150 /* Mute capture amp left and right */
6151 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6152 /* Set ADC connection select to match default mixer setting (mic1
6153 * pin)
7cf51e48
JW
6154 */
6155 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6156
6157 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6158 * set ADC connection to mic1 pin
7cf51e48
JW
6159 */
6160 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6161 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6162
6163 /* Mute all inputs to mixer widget (even unconnected ones) */
6164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6169 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6170 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6171 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6172
6173 { }
6174};
6175#endif
6176
6330079f
TI
6177#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6178#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6179
a3bcba38
TI
6180#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6181#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6182
df694daa
KY
6183/*
6184 * for BIOS auto-configuration
6185 */
16ded525 6186
df694daa 6187static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6188 const char *pfx, int *vol_bits)
df694daa
KY
6189{
6190 hda_nid_t nid_vol;
6191 unsigned long vol_val, sw_val;
df694daa
KY
6192 int err;
6193
6194 if (nid >= 0x0f && nid < 0x11) {
6195 nid_vol = nid - 0x7;
6196 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6197 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6198 } else if (nid == 0x11) {
6199 nid_vol = nid - 0x7;
6200 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6201 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6202 } else if (nid >= 0x12 && nid <= 0x15) {
6203 nid_vol = 0x08;
6204 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6205 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6206 } else
6207 return 0; /* N/A */
ea1fb29a 6208
863b4518
TI
6209 if (!(*vol_bits & (1 << nid_vol))) {
6210 /* first control for the volume widget */
0afe5f89 6211 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6212 if (err < 0)
6213 return err;
6214 *vol_bits |= (1 << nid_vol);
6215 }
0afe5f89 6216 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6217 if (err < 0)
df694daa
KY
6218 return err;
6219 return 1;
6220}
6221
6222/* add playback controls from the parsed DAC table */
6223static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6224 const struct auto_pin_cfg *cfg)
6225{
6226 hda_nid_t nid;
6227 int err;
863b4518 6228 int vols = 0;
df694daa
KY
6229
6230 spec->multiout.num_dacs = 1;
6231 spec->multiout.dac_nids = spec->private_dac_nids;
6232 spec->multiout.dac_nids[0] = 0x02;
6233
6234 nid = cfg->line_out_pins[0];
6235 if (nid) {
23112d6d
TI
6236 const char *pfx;
6237 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6238 pfx = "Master";
6239 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6240 pfx = "Speaker";
6241 else
6242 pfx = "Front";
6243 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6244 if (err < 0)
6245 return err;
6246 }
6247
82bc955f 6248 nid = cfg->speaker_pins[0];
df694daa 6249 if (nid) {
863b4518 6250 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6251 if (err < 0)
6252 return err;
6253 }
6254
eb06ed8f 6255 nid = cfg->hp_pins[0];
df694daa 6256 if (nid) {
863b4518
TI
6257 err = alc260_add_playback_controls(spec, nid, "Headphone",
6258 &vols);
df694daa
KY
6259 if (err < 0)
6260 return err;
6261 }
f12ab1e0 6262 return 0;
df694daa
KY
6263}
6264
6265/* create playback/capture controls for input pins */
05f5f477 6266static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6267 const struct auto_pin_cfg *cfg)
6268{
05f5f477 6269 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6270}
6271
6272static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6273 hda_nid_t nid, int pin_type,
6274 int sel_idx)
6275{
f6c7e546 6276 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6277 /* need the manual connection? */
6278 if (nid >= 0x12) {
6279 int idx = nid - 0x12;
6280 snd_hda_codec_write(codec, idx + 0x0b, 0,
6281 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6282 }
6283}
6284
6285static void alc260_auto_init_multi_out(struct hda_codec *codec)
6286{
6287 struct alc_spec *spec = codec->spec;
6288 hda_nid_t nid;
6289
f12ab1e0 6290 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6291 if (nid) {
6292 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6293 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6294 }
ea1fb29a 6295
82bc955f 6296 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6297 if (nid)
6298 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6299
eb06ed8f 6300 nid = spec->autocfg.hp_pins[0];
df694daa 6301 if (nid)
baba8ee9 6302 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6303}
df694daa
KY
6304
6305#define ALC260_PIN_CD_NID 0x16
6306static void alc260_auto_init_analog_input(struct hda_codec *codec)
6307{
6308 struct alc_spec *spec = codec->spec;
6309 int i;
6310
6311 for (i = 0; i < AUTO_PIN_LAST; i++) {
6312 hda_nid_t nid = spec->autocfg.input_pins[i];
6313 if (nid >= 0x12) {
23f0c048 6314 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6315 if (nid != ALC260_PIN_CD_NID &&
6316 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6317 snd_hda_codec_write(codec, nid, 0,
6318 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6319 AMP_OUT_MUTE);
6320 }
6321 }
6322}
6323
6324/*
6325 * generic initialization of ADC, input mixers and output mixers
6326 */
6327static struct hda_verb alc260_volume_init_verbs[] = {
6328 /*
6329 * Unmute ADC0-1 and set the default input to mic-in
6330 */
6331 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6332 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6333 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6334 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6335
df694daa
KY
6336 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6337 * mixer widget
f12ab1e0
TI
6338 * Note: PASD motherboards uses the Line In 2 as the input for
6339 * front panel mic (mic 2)
df694daa
KY
6340 */
6341 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6342 /* mute analog inputs */
6343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6347 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6348
6349 /*
6350 * Set up output mixers (0x08 - 0x0a)
6351 */
6352 /* set vol=0 to output mixers */
6353 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6354 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6355 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6356 /* set up input amps for analog loopback */
6357 /* Amp Indices: DAC = 0, mixer = 1 */
6358 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6359 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6360 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6361 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6362 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6363 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6364
df694daa
KY
6365 { }
6366};
6367
6368static int alc260_parse_auto_config(struct hda_codec *codec)
6369{
6370 struct alc_spec *spec = codec->spec;
df694daa
KY
6371 int err;
6372 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6373
f12ab1e0
TI
6374 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6375 alc260_ignore);
6376 if (err < 0)
df694daa 6377 return err;
f12ab1e0
TI
6378 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6379 if (err < 0)
4a471b7d 6380 return err;
603c4019 6381 if (!spec->kctls.list)
df694daa 6382 return 0; /* can't find valid BIOS pin config */
05f5f477 6383 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6384 if (err < 0)
df694daa
KY
6385 return err;
6386
6387 spec->multiout.max_channels = 2;
6388
0852d7a6 6389 if (spec->autocfg.dig_outs)
df694daa 6390 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6391 if (spec->kctls.list)
d88897ea 6392 add_mixer(spec, spec->kctls.list);
df694daa 6393
d88897ea 6394 add_verb(spec, alc260_volume_init_verbs);
df694daa 6395
a1e8d2da 6396 spec->num_mux_defs = 1;
61b9b9b1 6397 spec->input_mux = &spec->private_imux[0];
df694daa 6398
6227cdce 6399 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6400
df694daa
KY
6401 return 1;
6402}
6403
ae6b813a
TI
6404/* additional initialization for auto-configuration model */
6405static void alc260_auto_init(struct hda_codec *codec)
df694daa 6406{
f6c7e546 6407 struct alc_spec *spec = codec->spec;
df694daa
KY
6408 alc260_auto_init_multi_out(codec);
6409 alc260_auto_init_analog_input(codec);
f6c7e546 6410 if (spec->unsol_event)
7fb0d78f 6411 alc_inithook(codec);
df694daa
KY
6412}
6413
cb53c626
TI
6414#ifdef CONFIG_SND_HDA_POWER_SAVE
6415static struct hda_amp_list alc260_loopbacks[] = {
6416 { 0x07, HDA_INPUT, 0 },
6417 { 0x07, HDA_INPUT, 1 },
6418 { 0x07, HDA_INPUT, 2 },
6419 { 0x07, HDA_INPUT, 3 },
6420 { 0x07, HDA_INPUT, 4 },
6421 { } /* end */
6422};
6423#endif
6424
df694daa
KY
6425/*
6426 * ALC260 configurations
6427 */
f5fcc13c
TI
6428static const char *alc260_models[ALC260_MODEL_LAST] = {
6429 [ALC260_BASIC] = "basic",
6430 [ALC260_HP] = "hp",
6431 [ALC260_HP_3013] = "hp-3013",
2922c9af 6432 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6433 [ALC260_FUJITSU_S702X] = "fujitsu",
6434 [ALC260_ACER] = "acer",
bc9f98a9
KY
6435 [ALC260_WILL] = "will",
6436 [ALC260_REPLACER_672V] = "replacer",
cc959489 6437 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6438#ifdef CONFIG_SND_DEBUG
f5fcc13c 6439 [ALC260_TEST] = "test",
7cf51e48 6440#endif
f5fcc13c
TI
6441 [ALC260_AUTO] = "auto",
6442};
6443
6444static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6445 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6446 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6447 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6448 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6449 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6450 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6451 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6452 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6453 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6454 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6455 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6456 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6457 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6458 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6459 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6460 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6461 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6462 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6463 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6464 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6465 {}
6466};
6467
6468static struct alc_config_preset alc260_presets[] = {
6469 [ALC260_BASIC] = {
6470 .mixers = { alc260_base_output_mixer,
45bdd1c1 6471 alc260_input_mixer },
df694daa
KY
6472 .init_verbs = { alc260_init_verbs },
6473 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6474 .dac_nids = alc260_dac_nids,
f9e336f6 6475 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
6476 .adc_nids = alc260_adc_nids,
6477 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6478 .channel_mode = alc260_modes,
6479 .input_mux = &alc260_capture_source,
6480 },
6481 [ALC260_HP] = {
bec15c3a 6482 .mixers = { alc260_hp_output_mixer,
f9e336f6 6483 alc260_input_mixer },
bec15c3a
TI
6484 .init_verbs = { alc260_init_verbs,
6485 alc260_hp_unsol_verbs },
df694daa
KY
6486 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6487 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6488 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6489 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6490 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6491 .channel_mode = alc260_modes,
6492 .input_mux = &alc260_capture_source,
bec15c3a
TI
6493 .unsol_event = alc260_hp_unsol_event,
6494 .init_hook = alc260_hp_automute,
df694daa 6495 },
3f878308
KY
6496 [ALC260_HP_DC7600] = {
6497 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6498 alc260_input_mixer },
3f878308
KY
6499 .init_verbs = { alc260_init_verbs,
6500 alc260_hp_dc7600_verbs },
6501 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6502 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6503 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6504 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6505 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6506 .channel_mode = alc260_modes,
6507 .input_mux = &alc260_capture_source,
6508 .unsol_event = alc260_hp_3012_unsol_event,
6509 .init_hook = alc260_hp_3012_automute,
6510 },
df694daa
KY
6511 [ALC260_HP_3013] = {
6512 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6513 alc260_input_mixer },
bec15c3a
TI
6514 .init_verbs = { alc260_hp_3013_init_verbs,
6515 alc260_hp_3013_unsol_verbs },
df694daa
KY
6516 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6517 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6518 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6519 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6520 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6521 .channel_mode = alc260_modes,
6522 .input_mux = &alc260_capture_source,
bec15c3a
TI
6523 .unsol_event = alc260_hp_3013_unsol_event,
6524 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6525 },
6526 [ALC260_FUJITSU_S702X] = {
f9e336f6 6527 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6528 .init_verbs = { alc260_fujitsu_init_verbs },
6529 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6530 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6531 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6532 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6533 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6534 .channel_mode = alc260_modes,
a1e8d2da
JW
6535 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6536 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6537 },
0bfc90e9 6538 [ALC260_ACER] = {
f9e336f6 6539 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6540 .init_verbs = { alc260_acer_init_verbs },
6541 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6542 .dac_nids = alc260_dac_nids,
6543 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6544 .adc_nids = alc260_dual_adc_nids,
6545 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6546 .channel_mode = alc260_modes,
a1e8d2da
JW
6547 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6548 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6549 },
cc959489
MS
6550 [ALC260_FAVORIT100] = {
6551 .mixers = { alc260_favorit100_mixer },
6552 .init_verbs = { alc260_favorit100_init_verbs },
6553 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6554 .dac_nids = alc260_dac_nids,
6555 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6556 .adc_nids = alc260_dual_adc_nids,
6557 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6558 .channel_mode = alc260_modes,
6559 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6560 .input_mux = alc260_favorit100_capture_sources,
6561 },
bc9f98a9 6562 [ALC260_WILL] = {
f9e336f6 6563 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6564 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6565 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6566 .dac_nids = alc260_dac_nids,
6567 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6568 .adc_nids = alc260_adc_nids,
6569 .dig_out_nid = ALC260_DIGOUT_NID,
6570 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6571 .channel_mode = alc260_modes,
6572 .input_mux = &alc260_capture_source,
6573 },
6574 [ALC260_REPLACER_672V] = {
f9e336f6 6575 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6576 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6577 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6578 .dac_nids = alc260_dac_nids,
6579 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6580 .adc_nids = alc260_adc_nids,
6581 .dig_out_nid = ALC260_DIGOUT_NID,
6582 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6583 .channel_mode = alc260_modes,
6584 .input_mux = &alc260_capture_source,
6585 .unsol_event = alc260_replacer_672v_unsol_event,
6586 .init_hook = alc260_replacer_672v_automute,
6587 },
7cf51e48
JW
6588#ifdef CONFIG_SND_DEBUG
6589 [ALC260_TEST] = {
f9e336f6 6590 .mixers = { alc260_test_mixer },
7cf51e48
JW
6591 .init_verbs = { alc260_test_init_verbs },
6592 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6593 .dac_nids = alc260_test_dac_nids,
6594 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6595 .adc_nids = alc260_test_adc_nids,
6596 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6597 .channel_mode = alc260_modes,
a1e8d2da
JW
6598 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6599 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6600 },
6601#endif
df694daa
KY
6602};
6603
6604static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6605{
6606 struct alc_spec *spec;
df694daa 6607 int err, board_config;
1da177e4 6608
e560d8d8 6609 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6610 if (spec == NULL)
6611 return -ENOMEM;
6612
6613 codec->spec = spec;
6614
f5fcc13c
TI
6615 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6616 alc260_models,
6617 alc260_cfg_tbl);
6618 if (board_config < 0) {
9a11f1aa 6619 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6620 codec->chip_name);
df694daa 6621 board_config = ALC260_AUTO;
16ded525 6622 }
1da177e4 6623
df694daa
KY
6624 if (board_config == ALC260_AUTO) {
6625 /* automatic parse from the BIOS config */
6626 err = alc260_parse_auto_config(codec);
6627 if (err < 0) {
6628 alc_free(codec);
6629 return err;
f12ab1e0 6630 } else if (!err) {
9c7f852e
TI
6631 printk(KERN_INFO
6632 "hda_codec: Cannot set up configuration "
6633 "from BIOS. Using base mode...\n");
df694daa
KY
6634 board_config = ALC260_BASIC;
6635 }
a9430dd8 6636 }
e9edcee0 6637
680cd536
KK
6638 err = snd_hda_attach_beep_device(codec, 0x1);
6639 if (err < 0) {
6640 alc_free(codec);
6641 return err;
6642 }
6643
df694daa 6644 if (board_config != ALC260_AUTO)
e9c364c0 6645 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 6646
1da177e4
LT
6647 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6648 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6649
a3bcba38
TI
6650 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6651 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6652
4ef0ef19
TI
6653 if (!spec->adc_nids && spec->input_mux) {
6654 /* check whether NID 0x04 is valid */
6655 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 6656 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
6657 /* get type */
6658 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6659 spec->adc_nids = alc260_adc_nids_alt;
6660 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6661 } else {
6662 spec->adc_nids = alc260_adc_nids;
6663 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6664 }
6665 }
b59bdf3b 6666 set_capture_mixer(codec);
45bdd1c1 6667 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6668
2134ea4f
TI
6669 spec->vmaster_nid = 0x08;
6670
1da177e4 6671 codec->patch_ops = alc_patch_ops;
df694daa 6672 if (board_config == ALC260_AUTO)
ae6b813a 6673 spec->init_hook = alc260_auto_init;
cb53c626
TI
6674#ifdef CONFIG_SND_HDA_POWER_SAVE
6675 if (!spec->loopback.amplist)
6676 spec->loopback.amplist = alc260_loopbacks;
6677#endif
1da177e4
LT
6678
6679 return 0;
6680}
6681
e9edcee0 6682
1da177e4 6683/*
4953550a 6684 * ALC882/883/885/888/889 support
1da177e4
LT
6685 *
6686 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6687 * configuration. Each pin widget can choose any input DACs and a mixer.
6688 * Each ADC is connected from a mixer of all inputs. This makes possible
6689 * 6-channel independent captures.
6690 *
6691 * In addition, an independent DAC for the multi-playback (not used in this
6692 * driver yet).
6693 */
df694daa
KY
6694#define ALC882_DIGOUT_NID 0x06
6695#define ALC882_DIGIN_NID 0x0a
4953550a
TI
6696#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6697#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6698#define ALC1200_DIGOUT_NID 0x10
6699
1da177e4 6700
d2a6d7dc 6701static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6702 { 8, NULL }
6703};
6704
4953550a 6705/* DACs */
1da177e4
LT
6706static hda_nid_t alc882_dac_nids[4] = {
6707 /* front, rear, clfe, rear_surr */
6708 0x02, 0x03, 0x04, 0x05
6709};
4953550a 6710#define alc883_dac_nids alc882_dac_nids
1da177e4 6711
4953550a 6712/* ADCs */
df694daa
KY
6713#define alc882_adc_nids alc880_adc_nids
6714#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
6715#define alc883_adc_nids alc882_adc_nids_alt
6716static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6717static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6718#define alc889_adc_nids alc880_adc_nids
1da177e4 6719
e1406348
TI
6720static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6721static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
6722#define alc883_capsrc_nids alc882_capsrc_nids_alt
6723static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6724#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 6725
1da177e4
LT
6726/* input MUX */
6727/* FIXME: should be a matrix-type input source selection */
6728
6729static struct hda_input_mux alc882_capture_source = {
6730 .num_items = 4,
6731 .items = {
6732 { "Mic", 0x0 },
6733 { "Front Mic", 0x1 },
6734 { "Line", 0x2 },
6735 { "CD", 0x4 },
6736 },
6737};
41d5545d 6738
4953550a
TI
6739#define alc883_capture_source alc882_capture_source
6740
87a8c370
JK
6741static struct hda_input_mux alc889_capture_source = {
6742 .num_items = 3,
6743 .items = {
6744 { "Front Mic", 0x0 },
6745 { "Mic", 0x3 },
6746 { "Line", 0x2 },
6747 },
6748};
6749
41d5545d
KS
6750static struct hda_input_mux mb5_capture_source = {
6751 .num_items = 3,
6752 .items = {
6753 { "Mic", 0x1 },
6754 { "Line", 0x2 },
6755 { "CD", 0x4 },
6756 },
6757};
6758
e458b1fa
LY
6759static struct hda_input_mux macmini3_capture_source = {
6760 .num_items = 2,
6761 .items = {
6762 { "Line", 0x2 },
6763 { "CD", 0x4 },
6764 },
6765};
6766
4953550a
TI
6767static struct hda_input_mux alc883_3stack_6ch_intel = {
6768 .num_items = 4,
6769 .items = {
6770 { "Mic", 0x1 },
6771 { "Front Mic", 0x0 },
6772 { "Line", 0x2 },
6773 { "CD", 0x4 },
6774 },
6775};
6776
6777static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6778 .num_items = 2,
6779 .items = {
6780 { "Mic", 0x1 },
6781 { "Line", 0x2 },
6782 },
6783};
6784
6785static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6786 .num_items = 4,
6787 .items = {
6788 { "Mic", 0x0 },
6789 { "iMic", 0x1 },
6790 { "Line", 0x2 },
6791 { "CD", 0x4 },
6792 },
6793};
6794
6795static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6796 .num_items = 2,
6797 .items = {
6798 { "Mic", 0x0 },
6799 { "Int Mic", 0x1 },
6800 },
6801};
6802
6803static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6804 .num_items = 3,
6805 .items = {
6806 { "Mic", 0x0 },
6807 { "Front Mic", 0x1 },
6808 { "Line", 0x4 },
6809 },
6810};
6811
6812static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6813 .num_items = 2,
6814 .items = {
6815 { "Mic", 0x0 },
6816 { "Line", 0x2 },
6817 },
6818};
6819
6820static struct hda_input_mux alc889A_mb31_capture_source = {
6821 .num_items = 2,
6822 .items = {
6823 { "Mic", 0x0 },
6824 /* Front Mic (0x01) unused */
6825 { "Line", 0x2 },
6826 /* Line 2 (0x03) unused */
af901ca1 6827 /* CD (0x04) unused? */
4953550a
TI
6828 },
6829};
6830
6831/*
6832 * 2ch mode
6833 */
6834static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6835 { 2, NULL }
6836};
6837
272a527c
KY
6838/*
6839 * 2ch mode
6840 */
6841static struct hda_verb alc882_3ST_ch2_init[] = {
6842 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6843 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6844 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6845 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6846 { } /* end */
6847};
6848
4953550a
TI
6849/*
6850 * 4ch mode
6851 */
6852static struct hda_verb alc882_3ST_ch4_init[] = {
6853 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6854 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6855 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6856 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6857 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6858 { } /* end */
6859};
6860
272a527c
KY
6861/*
6862 * 6ch mode
6863 */
6864static struct hda_verb alc882_3ST_ch6_init[] = {
6865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6867 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6868 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6869 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6870 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6871 { } /* end */
6872};
6873
4953550a 6874static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 6875 { 2, alc882_3ST_ch2_init },
4953550a 6876 { 4, alc882_3ST_ch4_init },
272a527c
KY
6877 { 6, alc882_3ST_ch6_init },
6878};
6879
4953550a
TI
6880#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6881
a65cc60f 6882/*
6883 * 2ch mode
6884 */
6885static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6886 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6887 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6888 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6889 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6890 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6891 { } /* end */
6892};
6893
6894/*
6895 * 4ch mode
6896 */
6897static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6898 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6899 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6900 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6901 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6902 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6903 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6904 { } /* end */
6905};
6906
6907/*
6908 * 6ch mode
6909 */
6910static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6911 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6912 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6913 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6914 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6915 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6916 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6917 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6918 { } /* end */
6919};
6920
6921static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6922 { 2, alc883_3ST_ch2_clevo_init },
6923 { 4, alc883_3ST_ch4_clevo_init },
6924 { 6, alc883_3ST_ch6_clevo_init },
6925};
6926
6927
df694daa
KY
6928/*
6929 * 6ch mode
6930 */
6931static struct hda_verb alc882_sixstack_ch6_init[] = {
6932 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6933 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6934 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6935 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6936 { } /* end */
6937};
6938
6939/*
6940 * 8ch mode
6941 */
6942static struct hda_verb alc882_sixstack_ch8_init[] = {
6943 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6944 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6945 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6946 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6947 { } /* end */
6948};
6949
6950static struct hda_channel_mode alc882_sixstack_modes[2] = {
6951 { 6, alc882_sixstack_ch6_init },
6952 { 8, alc882_sixstack_ch8_init },
6953};
6954
76e6f5a9
RH
6955
6956/* Macbook Air 2,1 */
6957
6958static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
6959 { 2, NULL },
6960};
6961
87350ad0 6962/*
def319f9 6963 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
6964 */
6965
6966/*
6967 * 2ch mode
6968 */
6969static struct hda_verb alc885_mbp_ch2_init[] = {
6970 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6971 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6972 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6973 { } /* end */
6974};
6975
6976/*
a3f730af 6977 * 4ch mode
87350ad0 6978 */
a3f730af 6979static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
6980 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6981 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6982 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6983 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6984 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6985 { } /* end */
6986};
6987
a3f730af 6988static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 6989 { 2, alc885_mbp_ch2_init },
a3f730af 6990 { 4, alc885_mbp_ch4_init },
87350ad0
TI
6991};
6992
92b9de83
KS
6993/*
6994 * 2ch
6995 * Speakers/Woofer/HP = Front
6996 * LineIn = Input
6997 */
6998static struct hda_verb alc885_mb5_ch2_init[] = {
6999 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7001 { } /* end */
7002};
7003
7004/*
7005 * 6ch mode
7006 * Speakers/HP = Front
7007 * Woofer = LFE
7008 * LineIn = Surround
7009 */
7010static struct hda_verb alc885_mb5_ch6_init[] = {
7011 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7013 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7014 { } /* end */
7015};
7016
7017static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7018 { 2, alc885_mb5_ch2_init },
7019 { 6, alc885_mb5_ch6_init },
7020};
87350ad0 7021
d01aecdf 7022#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7023
7024/*
7025 * 2ch mode
7026 */
7027static struct hda_verb alc883_4ST_ch2_init[] = {
7028 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7029 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7030 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7031 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7033 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7034 { } /* end */
7035};
7036
7037/*
7038 * 4ch mode
7039 */
7040static struct hda_verb alc883_4ST_ch4_init[] = {
7041 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7042 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7043 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7044 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7045 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7046 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7047 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7048 { } /* end */
7049};
7050
7051/*
7052 * 6ch mode
7053 */
7054static struct hda_verb alc883_4ST_ch6_init[] = {
7055 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7056 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7057 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7058 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7059 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7060 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7061 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7062 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7063 { } /* end */
7064};
7065
7066/*
7067 * 8ch mode
7068 */
7069static struct hda_verb alc883_4ST_ch8_init[] = {
7070 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7071 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7072 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7073 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7074 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7075 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7076 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7077 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7078 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7079 { } /* end */
7080};
7081
7082static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7083 { 2, alc883_4ST_ch2_init },
7084 { 4, alc883_4ST_ch4_init },
7085 { 6, alc883_4ST_ch6_init },
7086 { 8, alc883_4ST_ch8_init },
7087};
7088
7089
7090/*
7091 * 2ch mode
7092 */
7093static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7094 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7095 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7096 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7097 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7098 { } /* end */
7099};
7100
7101/*
7102 * 4ch mode
7103 */
7104static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7105 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7106 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7107 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7108 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7109 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7110 { } /* end */
7111};
7112
7113/*
7114 * 6ch mode
7115 */
7116static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7117 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7118 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7119 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7120 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7121 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7122 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7123 { } /* end */
7124};
7125
7126static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7127 { 2, alc883_3ST_ch2_intel_init },
7128 { 4, alc883_3ST_ch4_intel_init },
7129 { 6, alc883_3ST_ch6_intel_init },
7130};
7131
dd7714c9
WF
7132/*
7133 * 2ch mode
7134 */
7135static struct hda_verb alc889_ch2_intel_init[] = {
7136 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7137 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7138 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7139 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7140 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7141 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7142 { } /* end */
7143};
7144
87a8c370
JK
7145/*
7146 * 6ch mode
7147 */
7148static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7149 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7150 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7151 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7152 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7153 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7154 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7155 { } /* end */
7156};
7157
7158/*
7159 * 8ch mode
7160 */
7161static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7162 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7163 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7164 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7165 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7166 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7167 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7168 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7169 { } /* end */
7170};
7171
dd7714c9
WF
7172static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7173 { 2, alc889_ch2_intel_init },
87a8c370
JK
7174 { 6, alc889_ch6_intel_init },
7175 { 8, alc889_ch8_intel_init },
7176};
7177
4953550a
TI
7178/*
7179 * 6ch mode
7180 */
7181static struct hda_verb alc883_sixstack_ch6_init[] = {
7182 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7183 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7184 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7185 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7186 { } /* end */
7187};
7188
7189/*
7190 * 8ch mode
7191 */
7192static struct hda_verb alc883_sixstack_ch8_init[] = {
7193 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7194 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7195 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7196 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7197 { } /* end */
7198};
7199
7200static struct hda_channel_mode alc883_sixstack_modes[2] = {
7201 { 6, alc883_sixstack_ch6_init },
7202 { 8, alc883_sixstack_ch8_init },
7203};
7204
7205
1da177e4
LT
7206/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7207 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7208 */
c8b6bf9b 7209static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7213 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7214 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7215 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7216 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7217 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7218 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7219 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7221 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7222 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7226 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7229 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7230 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7231 { } /* end */
7232};
7233
76e6f5a9
RH
7234/* Macbook Air 2,1 same control for HP and internal Speaker */
7235
7236static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7237 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7238 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7239 { }
7240};
7241
7242
87350ad0 7243static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7245 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7246 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7247 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7248 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7249 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7250 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7252 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7253 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7255 { } /* end */
7256};
41d5545d
KS
7257
7258static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7259 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7260 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7261 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7262 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7263 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7264 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7265 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7266 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
41d5545d
KS
7267 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7268 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7269 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7270 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7271 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7272 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7273 { } /* end */
7274};
92b9de83 7275
e458b1fa
LY
7276static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7278 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7280 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7281 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7282 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7284 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7288 { } /* end */
7289};
7290
4b7e1803
JM
7291static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7292 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7293 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
7294 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7295 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7296 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7297 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7299 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7300 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7301 { } /* end */
7302};
7303
7304
bdd148a3
KY
7305static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7306 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7308 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7309 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7311 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7313 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7314 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7315 { } /* end */
7316};
7317
272a527c
KY
7318static struct snd_kcontrol_new alc882_targa_mixer[] = {
7319 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7320 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7321 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7322 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7323 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7324 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7325 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7326 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7327 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7328 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7329 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7330 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7331 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7332 { } /* end */
7333};
7334
7335/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7336 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7337 */
7338static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7340 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7342 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7343 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7344 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7345 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7346 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7347 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7348 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7351 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7352 { } /* end */
7353};
7354
914759b7
TI
7355static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7356 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7357 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7358 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7359 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7360 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7361 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7362 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7364 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7366 { } /* end */
7367};
7368
df694daa
KY
7369static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7370 {
7371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7372 .name = "Channel Mode",
7373 .info = alc_ch_mode_info,
7374 .get = alc_ch_mode_get,
7375 .put = alc_ch_mode_put,
7376 },
7377 { } /* end */
7378};
7379
4953550a 7380static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7381 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7384 /* Rear mixer */
05acb863
TI
7385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7387 /* CLFE mixer */
05acb863
TI
7388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7390 /* Side mixer */
05acb863
TI
7391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7393
e9edcee0 7394 /* Front Pin: output 0 (0x0c) */
05acb863 7395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7396 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7397 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7398 /* Rear Pin: output 1 (0x0d) */
05acb863 7399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7401 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7402 /* CLFE Pin: output 2 (0x0e) */
05acb863 7403 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7404 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7405 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7406 /* Side Pin: output 3 (0x0f) */
05acb863 7407 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7408 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7409 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7410 /* Mic (rear) pin: input vref at 80% */
16ded525 7411 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7413 /* Front Mic pin: input vref at 80% */
16ded525 7414 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7415 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7416 /* Line In pin: input */
05acb863 7417 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7418 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7419 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7420 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7421 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7422 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7423 /* CD pin widget for input */
05acb863 7424 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7425
7426 /* FIXME: use matrix-type input source selection */
7427 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7428 /* Input mixer2 */
05acb863 7429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7430 /* Input mixer3 */
05acb863 7431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7432 /* ADC2: mute amp left and right */
7433 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7435 /* ADC3: mute amp left and right */
7436 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7437 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7438
7439 { }
7440};
7441
4953550a
TI
7442static struct hda_verb alc882_adc1_init_verbs[] = {
7443 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7448 /* ADC1: mute amp left and right */
7449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7450 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7451 { }
7452};
7453
4b146cb0
TI
7454static struct hda_verb alc882_eapd_verbs[] = {
7455 /* change to EAPD mode */
7456 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7457 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7458 { }
4b146cb0
TI
7459};
7460
87a8c370
JK
7461static struct hda_verb alc889_eapd_verbs[] = {
7462 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7463 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7464 { }
7465};
7466
6732bd0d
WF
7467static struct hda_verb alc_hp15_unsol_verbs[] = {
7468 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7470 {}
7471};
87a8c370
JK
7472
7473static struct hda_verb alc885_init_verbs[] = {
7474 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7477 /* Rear mixer */
88102f3f
KY
7478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7480 /* CLFE mixer */
88102f3f
KY
7481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7483 /* Side mixer */
88102f3f
KY
7484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7486
7487 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7491 /* Front Pin: output 0 (0x0c) */
7492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7493 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7494 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7495 /* Rear Pin: output 1 (0x0d) */
7496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7498 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7499 /* CLFE Pin: output 2 (0x0e) */
7500 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7502 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7503 /* Side Pin: output 3 (0x0f) */
7504 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7506 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7507 /* Mic (rear) pin: input vref at 80% */
7508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7510 /* Front Mic pin: input vref at 80% */
7511 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7512 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7513 /* Line In pin: input */
7514 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7516
7517 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7518 /* Input mixer1 */
88102f3f 7519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7520 /* Input mixer2 */
7521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7522 /* Input mixer3 */
88102f3f 7523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7524 /* ADC2: mute amp left and right */
7525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7526 /* ADC3: mute amp left and right */
7527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7528
7529 { }
7530};
7531
7532static struct hda_verb alc885_init_input_verbs[] = {
7533 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7534 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7535 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7536 { }
7537};
7538
7539
7540/* Unmute Selector 24h and set the default input to front mic */
7541static struct hda_verb alc889_init_input_verbs[] = {
7542 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7544 { }
7545};
7546
7547
4953550a
TI
7548#define alc883_init_verbs alc882_base_init_verbs
7549
9102cd1c
TD
7550/* Mac Pro test */
7551static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7552 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7553 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7555 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7556 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7557 /* FIXME: this looks suspicious...
d355c82a
JK
7558 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7559 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7560 */
9102cd1c
TD
7561 { } /* end */
7562};
7563
7564static struct hda_verb alc882_macpro_init_verbs[] = {
7565 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7569 /* Front Pin: output 0 (0x0c) */
7570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7572 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7573 /* Front Mic pin: input vref at 80% */
7574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7575 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7576 /* Speaker: output */
7577 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7578 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7579 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7580 /* Headphone output (output 0 - 0x0c) */
7581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7583 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7584
7585 /* FIXME: use matrix-type input source selection */
7586 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7587 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7588 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7589 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7592 /* Input mixer2 */
7593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7597 /* Input mixer3 */
7598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7602 /* ADC1: mute amp left and right */
7603 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7604 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7605 /* ADC2: mute amp left and right */
7606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7607 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7608 /* ADC3: mute amp left and right */
7609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7610 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7611
7612 { }
7613};
f12ab1e0 7614
41d5545d
KS
7615/* Macbook 5,1 */
7616static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7617 /* DACs */
7618 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7619 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7620 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7621 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7622 /* Front mixer */
41d5545d
KS
7623 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7626 /* Surround mixer */
7627 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7628 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7630 /* LFE mixer */
7631 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7634 /* HP mixer */
7635 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7638 /* Front Pin (0x0c) */
41d5545d
KS
7639 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
7641 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7642 /* LFE Pin (0x0e) */
7643 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7644 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7645 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7646 /* HP Pin (0x0f) */
41d5545d
KS
7647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 7649 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 7650 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
7651 /* Front Mic pin: input vref at 80% */
7652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7654 /* Line In pin */
7655 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7657
7658 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7659 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7660 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7662 { }
7663};
7664
e458b1fa
LY
7665/* Macmini 3,1 */
7666static struct hda_verb alc885_macmini3_init_verbs[] = {
7667 /* DACs */
7668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7672 /* Front mixer */
7673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7676 /* Surround mixer */
7677 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7680 /* LFE mixer */
7681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 /* HP mixer */
7685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7686 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7688 /* Front Pin (0x0c) */
7689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7691 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7692 /* LFE Pin (0x0e) */
7693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7696 /* HP Pin (0x0f) */
7697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7701 /* Line In pin */
7702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7704
7705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7709 { }
7710};
7711
76e6f5a9
RH
7712
7713static struct hda_verb alc885_mba21_init_verbs[] = {
7714 /*Internal and HP Speaker Mixer*/
7715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7718 /*Internal Speaker Pin (0x0c)*/
7719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7722 /* HP Pin: output 0 (0x0e) */
7723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7727 /* Line in (is hp when jack connected)*/
7728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7730
7731 { }
7732 };
7733
7734
87350ad0
TI
7735/* Macbook Pro rev3 */
7736static struct hda_verb alc885_mbp3_init_verbs[] = {
7737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7741 /* Rear mixer */
7742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7743 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
7745 /* HP mixer */
7746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
7749 /* Front Pin: output 0 (0x0c) */
7750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7751 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7752 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 7753 /* HP Pin: output 0 (0x0e) */
87350ad0 7754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
7755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
7757 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7758 /* Mic (rear) pin: input vref at 80% */
7759 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7760 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7761 /* Front Mic pin: input vref at 80% */
7762 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7763 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7764 /* Line In pin: use output 1 when in LineOut mode */
7765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7766 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7767 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7768
7769 /* FIXME: use matrix-type input source selection */
7770 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7771 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7776 /* Input mixer2 */
7777 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7778 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7779 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7780 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7781 /* Input mixer3 */
7782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7783 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7784 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7786 /* ADC1: mute amp left and right */
7787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7788 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7789 /* ADC2: mute amp left and right */
7790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7792 /* ADC3: mute amp left and right */
7793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7794 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7795
7796 { }
7797};
7798
4b7e1803
JM
7799/* iMac 9,1 */
7800static struct hda_verb alc885_imac91_init_verbs[] = {
7801 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7803 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7805 /* Rear mixer */
7806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7809 /* HP Pin: output 0 (0x0c) */
7810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7811 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7812 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7813 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7814 /* Internal Speakers: output 0 (0x0d) */
7815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7817 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7818 /* Mic (rear) pin: input vref at 80% */
7819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7820 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7821 /* Front Mic pin: input vref at 80% */
7822 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7824 /* Line In pin: use output 1 when in LineOut mode */
7825 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7827 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7828
7829 /* FIXME: use matrix-type input source selection */
7830 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7831 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7832 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7833 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7834 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7835 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7836 /* Input mixer2 */
7837 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7838 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7840 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7841 /* Input mixer3 */
7842 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7843 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7844 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7846 /* ADC1: mute amp left and right */
7847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7848 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7849 /* ADC2: mute amp left and right */
7850 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7851 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7852 /* ADC3: mute amp left and right */
7853 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7854 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7855
7856 { }
7857};
7858
c54728d8
NF
7859/* iMac 24 mixer. */
7860static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7861 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7862 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7863 { } /* end */
7864};
7865
7866/* iMac 24 init verbs. */
7867static struct hda_verb alc885_imac24_init_verbs[] = {
7868 /* Internal speakers: output 0 (0x0c) */
7869 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7870 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7871 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7872 /* Internal speakers: output 0 (0x0c) */
7873 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7875 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7876 /* Headphone: output 0 (0x0c) */
7877 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7879 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7880 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7881 /* Front Mic: input vref at 80% */
7882 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7883 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7884 { }
7885};
7886
7887/* Toggle speaker-output according to the hp-jack state */
4f5d1706 7888static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 7889{
a9fd4f3f 7890 struct alc_spec *spec = codec->spec;
c54728d8 7891
a9fd4f3f
TI
7892 spec->autocfg.hp_pins[0] = 0x14;
7893 spec->autocfg.speaker_pins[0] = 0x18;
7894 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
7895}
7896
9d54f08b
TI
7897#define alc885_mb5_setup alc885_imac24_setup
7898#define alc885_macmini3_setup alc885_imac24_setup
7899
76e6f5a9
RH
7900/* Macbook Air 2,1 */
7901static void alc885_mba21_setup(struct hda_codec *codec)
7902{
7903 struct alc_spec *spec = codec->spec;
7904
7905 spec->autocfg.hp_pins[0] = 0x14;
7906 spec->autocfg.speaker_pins[0] = 0x18;
7907}
7908
7909
7910
4f5d1706 7911static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 7912{
a9fd4f3f 7913 struct alc_spec *spec = codec->spec;
87350ad0 7914
a9fd4f3f
TI
7915 spec->autocfg.hp_pins[0] = 0x15;
7916 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
7917}
7918
9d54f08b 7919static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 7920{
9d54f08b 7921 struct alc_spec *spec = codec->spec;
4b7e1803 7922
9d54f08b
TI
7923 spec->autocfg.hp_pins[0] = 0x14;
7924 spec->autocfg.speaker_pins[0] = 0x15;
7925 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 7926}
87350ad0 7927
272a527c
KY
7928static struct hda_verb alc882_targa_verbs[] = {
7929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7931
7932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7934
272a527c
KY
7935 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7936 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7937 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7938
7939 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
7940 { } /* end */
7941};
7942
7943/* toggle speaker-output according to the hp-jack state */
7944static void alc882_targa_automute(struct hda_codec *codec)
7945{
a9fd4f3f
TI
7946 struct alc_spec *spec = codec->spec;
7947 alc_automute_amp(codec);
82beb8fd 7948 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
7949 spec->jack_present ? 1 : 3);
7950}
7951
4f5d1706 7952static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
7953{
7954 struct alc_spec *spec = codec->spec;
7955
7956 spec->autocfg.hp_pins[0] = 0x14;
7957 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
7958}
7959
7960static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7961{
a9fd4f3f 7962 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 7963 alc882_targa_automute(codec);
272a527c
KY
7964}
7965
7966static struct hda_verb alc882_asus_a7j_verbs[] = {
7967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7969
7970 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7971 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7972 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7973
272a527c
KY
7974 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7975 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7976 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7977
7978 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7979 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7980 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7981 { } /* end */
7982};
7983
914759b7
TI
7984static struct hda_verb alc882_asus_a7m_verbs[] = {
7985 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7987
7988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7991
914759b7
TI
7992 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7993 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7995
7996 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7997 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7998 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7999 { } /* end */
8000};
8001
9102cd1c
TD
8002static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8003{
8004 unsigned int gpiostate, gpiomask, gpiodir;
8005
8006 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8007 AC_VERB_GET_GPIO_DATA, 0);
8008
8009 if (!muted)
8010 gpiostate |= (1 << pin);
8011 else
8012 gpiostate &= ~(1 << pin);
8013
8014 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8015 AC_VERB_GET_GPIO_MASK, 0);
8016 gpiomask |= (1 << pin);
8017
8018 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8019 AC_VERB_GET_GPIO_DIRECTION, 0);
8020 gpiodir |= (1 << pin);
8021
8022
8023 snd_hda_codec_write(codec, codec->afg, 0,
8024 AC_VERB_SET_GPIO_MASK, gpiomask);
8025 snd_hda_codec_write(codec, codec->afg, 0,
8026 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8027
8028 msleep(1);
8029
8030 snd_hda_codec_write(codec, codec->afg, 0,
8031 AC_VERB_SET_GPIO_DATA, gpiostate);
8032}
8033
7debbe51
TI
8034/* set up GPIO at initialization */
8035static void alc885_macpro_init_hook(struct hda_codec *codec)
8036{
8037 alc882_gpio_mute(codec, 0, 0);
8038 alc882_gpio_mute(codec, 1, 0);
8039}
8040
8041/* set up GPIO and update auto-muting at initialization */
8042static void alc885_imac24_init_hook(struct hda_codec *codec)
8043{
8044 alc885_macpro_init_hook(codec);
4f5d1706 8045 alc_automute_amp(codec);
7debbe51
TI
8046}
8047
df694daa
KY
8048/*
8049 * generic initialization of ADC, input mixers and output mixers
8050 */
4953550a 8051static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8052 /*
8053 * Unmute ADC0-2 and set the default input to mic-in
8054 */
4953550a
TI
8055 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8056 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8059
4953550a
TI
8060 /*
8061 * Set up output mixers (0x0c - 0x0f)
8062 */
8063 /* set vol=0 to output mixers */
8064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8065 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8068 /* set up input amps for analog loopback */
8069 /* Amp Indices: DAC = 0, mixer = 1 */
8070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8072 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8074 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8075 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8076 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8077 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8078 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8079 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8080
4953550a
TI
8081 /* FIXME: use matrix-type input source selection */
8082 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8083 /* Input mixer2 */
88102f3f 8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8085 /* Input mixer3 */
88102f3f 8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8087 { }
9c7f852e
TI
8088};
8089
eb4c41d3
TS
8090/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8091static struct hda_verb alc889A_mb31_ch2_init[] = {
8092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8096 { } /* end */
8097};
8098
8099/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8100static struct hda_verb alc889A_mb31_ch4_init[] = {
8101 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8104 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8105 { } /* end */
8106};
8107
8108/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8109static struct hda_verb alc889A_mb31_ch5_init[] = {
8110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8113 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8114 { } /* end */
8115};
8116
8117/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8118static struct hda_verb alc889A_mb31_ch6_init[] = {
8119 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8120 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8121 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8122 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8123 { } /* end */
8124};
8125
8126static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8127 { 2, alc889A_mb31_ch2_init },
8128 { 4, alc889A_mb31_ch4_init },
8129 { 5, alc889A_mb31_ch5_init },
8130 { 6, alc889A_mb31_ch6_init },
8131};
8132
b373bdeb
AN
8133static struct hda_verb alc883_medion_eapd_verbs[] = {
8134 /* eanable EAPD on medion laptop */
8135 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8136 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8137 { }
8138};
8139
4953550a 8140#define alc883_base_mixer alc882_base_mixer
834be88d 8141
a8848bd6
AS
8142static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8145 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8146 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8147 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8148 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8151 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8152 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8153 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8154 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8155 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8156 { } /* end */
8157};
8158
0c4cc443 8159static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8160 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8161 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8163 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8165 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8167 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8168 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8169 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8170 { } /* end */
8171};
8172
fb97dc67
J
8173static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8174 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8175 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8176 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8177 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8179 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8181 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8182 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8183 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8184 { } /* end */
8185};
8186
9c7f852e
TI
8187static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8188 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8189 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8190 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8191 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8192 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8193 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8194 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8196 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8199 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8200 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8201 { } /* end */
8202};
df694daa 8203
9c7f852e
TI
8204static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8214 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8215 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8217 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8219 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8221 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8222 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8223 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8224 { } /* end */
8225};
8226
17bba1b7
J
8227static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8228 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8229 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8230 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8231 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8233 HDA_OUTPUT),
8234 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8235 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8236 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8238 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8239 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8240 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8241 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8243 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8245 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8246 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8247 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8248 { } /* end */
8249};
8250
87a8c370
JK
8251static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8253 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8254 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8255 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8256 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8257 HDA_OUTPUT),
8258 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8259 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8260 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8261 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8262 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8270 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8271 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8272 { } /* end */
8273};
8274
d1d985f0 8275static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8276 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8277 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8278 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8279 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8280 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8281 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8282 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8283 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8285 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8286 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8287 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8288 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8289 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8290 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8292 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8294 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8295 { } /* end */
8296};
8297
c259249f 8298static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8302 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8303 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8304 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8305 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8306 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8307 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8308 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8309 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8310 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8314 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8316 { } /* end */
f12ab1e0 8317};
ccc656ce 8318
c259249f 8319static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8322 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8323 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8324 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8325 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8326 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8327 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8329 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8330 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8331 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8332 { } /* end */
f12ab1e0 8333};
ccc656ce 8334
b99dba34
TI
8335static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8336 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8337 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8338 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8339 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8340 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8341 { } /* end */
8342};
8343
bc9f98a9
KY
8344static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8347 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8348 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8349 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8353 { } /* end */
f12ab1e0 8354};
bc9f98a9 8355
272a527c
KY
8356static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8357 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8358 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8359 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8360 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8361 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8363 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8364 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8365 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8366 { } /* end */
8367};
8368
8369static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8371 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8372 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8377 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8378 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8379 { } /* end */
ea1fb29a 8380};
272a527c 8381
2880a867 8382static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8383 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8384 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8385 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8386 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8387 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8389 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8390 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8391 { } /* end */
d1a991a6 8392};
2880a867 8393
d2fd4b09
TV
8394static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8395 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8396 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8397 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8398 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
684a8842
TV
8399 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8400 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8401 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8402 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8406 { } /* end */
8407};
8408
e2757d5e
KY
8409static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8410 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8411 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8412 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8413 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8414 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8415 0x0d, 1, 0x0, HDA_OUTPUT),
8416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8418 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8419 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8420 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8426 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8428 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8429 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8430 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8431 { } /* end */
8432};
8433
eb4c41d3
TS
8434static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8435 /* Output mixers */
8436 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8437 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8438 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8439 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8440 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8441 HDA_OUTPUT),
8442 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8443 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8444 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8445 /* Output switches */
8446 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8447 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8448 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8449 /* Boost mixers */
8450 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8451 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8452 /* Input mixers */
8453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8457 { } /* end */
8458};
8459
3e1647c5
GG
8460static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8461 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8462 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8465 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8467 { } /* end */
8468};
8469
e2757d5e
KY
8470static struct hda_bind_ctls alc883_bind_cap_vol = {
8471 .ops = &snd_hda_bind_vol,
8472 .values = {
8473 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8474 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8475 0
8476 },
8477};
8478
8479static struct hda_bind_ctls alc883_bind_cap_switch = {
8480 .ops = &snd_hda_bind_sw,
8481 .values = {
8482 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8483 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8484 0
8485 },
8486};
8487
8488static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8489 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8490 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8492 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8493 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8495 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8497 { } /* end */
8498};
df694daa 8499
4953550a
TI
8500static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8501 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8502 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8503 {
8504 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8505 /* .name = "Capture Source", */
8506 .name = "Input Source",
8507 .count = 1,
8508 .info = alc_mux_enum_info,
8509 .get = alc_mux_enum_get,
8510 .put = alc_mux_enum_put,
8511 },
8512 { } /* end */
8513};
9c7f852e 8514
4953550a
TI
8515static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8516 {
8517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8518 .name = "Channel Mode",
8519 .info = alc_ch_mode_info,
8520 .get = alc_ch_mode_get,
8521 .put = alc_ch_mode_put,
8522 },
8523 { } /* end */
9c7f852e
TI
8524};
8525
a8848bd6 8526/* toggle speaker-output according to the hp-jack state */
4f5d1706 8527static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8528{
a9fd4f3f 8529 struct alc_spec *spec = codec->spec;
a8848bd6 8530
a9fd4f3f
TI
8531 spec->autocfg.hp_pins[0] = 0x15;
8532 spec->autocfg.speaker_pins[0] = 0x14;
8533 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8534}
8535
8536/* auto-toggle front mic */
8537/*
8538static void alc883_mitac_mic_automute(struct hda_codec *codec)
8539{
864f92be 8540 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8541
a8848bd6
AS
8542 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8543}
8544*/
8545
a8848bd6
AS
8546static struct hda_verb alc883_mitac_verbs[] = {
8547 /* HP */
8548 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8549 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8550 /* Subwoofer */
8551 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8552 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8553
8554 /* enable unsolicited event */
8555 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8556 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8557
8558 { } /* end */
8559};
8560
a65cc60f 8561static struct hda_verb alc883_clevo_m540r_verbs[] = {
8562 /* HP */
8563 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8565 /* Int speaker */
8566 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8567
8568 /* enable unsolicited event */
8569 /*
8570 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8571 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8572 */
8573
8574 { } /* end */
8575};
8576
0c4cc443 8577static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8578 /* HP */
8579 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8581 /* Int speaker */
8582 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8584
8585 /* enable unsolicited event */
8586 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8587 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8588
8589 { } /* end */
8590};
8591
fb97dc67
J
8592static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8593 /* HP */
8594 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8596 /* Subwoofer */
8597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8598 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8599
8600 /* enable unsolicited event */
8601 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8602
8603 { } /* end */
8604};
8605
c259249f 8606static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8609
8610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8611 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8612
64a8be74
DH
8613/* Connect Line-Out side jack (SPDIF) to Side */
8614 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8615 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8616 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8617/* Connect Mic jack to CLFE */
8618 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8620 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8621/* Connect Line-in jack to Surround */
8622 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8624 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8625/* Connect HP out jack to Front */
8626 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8627 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8628 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
8629
8630 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
8631
8632 { } /* end */
8633};
8634
bc9f98a9
KY
8635static struct hda_verb alc883_lenovo_101e_verbs[] = {
8636 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8637 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8638 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8639 { } /* end */
8640};
8641
272a527c
KY
8642static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8644 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8645 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8647 { } /* end */
8648};
8649
8650static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8653 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8654 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8655 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8656 { } /* end */
8657};
8658
189609ae
KY
8659static struct hda_verb alc883_haier_w66_verbs[] = {
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8662
8663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8664
8665 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8667 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8668 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8669 { } /* end */
8670};
8671
e2757d5e
KY
8672static struct hda_verb alc888_lenovo_sky_verbs[] = {
8673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8675 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8676 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8677 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8679 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8680 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8681 { } /* end */
8682};
8683
8718b700
HRK
8684static struct hda_verb alc888_6st_dell_verbs[] = {
8685 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8686 { }
8687};
8688
3e1647c5
GG
8689static struct hda_verb alc883_vaiott_verbs[] = {
8690 /* HP */
8691 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8693
8694 /* enable unsolicited event */
8695 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8696
8697 { } /* end */
8698};
8699
4f5d1706 8700static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 8701{
a9fd4f3f 8702 struct alc_spec *spec = codec->spec;
8718b700 8703
a9fd4f3f
TI
8704 spec->autocfg.hp_pins[0] = 0x1b;
8705 spec->autocfg.speaker_pins[0] = 0x14;
8706 spec->autocfg.speaker_pins[1] = 0x16;
8707 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
8708}
8709
4723c022 8710static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8711 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8712 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8713 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8714 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8715 { } /* end */
5795b9e6
CM
8716};
8717
3ea0d7cf
HRK
8718/*
8719 * 2ch mode
8720 */
4723c022 8721static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8722 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8723 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8724 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8725 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8726 { } /* end */
8341de60
CM
8727};
8728
3ea0d7cf
HRK
8729/*
8730 * 4ch mode
8731 */
8732static struct hda_verb alc888_3st_hp_4ch_init[] = {
8733 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8734 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8735 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8736 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8737 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8738 { } /* end */
8739};
8740
8741/*
8742 * 6ch mode
8743 */
4723c022 8744static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8745 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8746 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8747 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8748 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8749 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8750 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8751 { } /* end */
8341de60
CM
8752};
8753
3ea0d7cf 8754static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8755 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8756 { 4, alc888_3st_hp_4ch_init },
4723c022 8757 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8758};
8759
272a527c
KY
8760/* toggle front-jack and RCA according to the hp-jack state */
8761static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8762{
864f92be 8763 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 8764
47fd830a
TI
8765 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8766 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8767 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8768 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8769}
8770
8771/* toggle RCA according to the front-jack state */
8772static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8773{
864f92be 8774 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 8775
47fd830a
TI
8776 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8777 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8778}
47fd830a 8779
272a527c
KY
8780static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8781 unsigned int res)
8782{
8783 if ((res >> 26) == ALC880_HP_EVENT)
8784 alc888_lenovo_ms7195_front_automute(codec);
8785 if ((res >> 26) == ALC880_FRONT_EVENT)
8786 alc888_lenovo_ms7195_rca_automute(codec);
8787}
8788
8789static struct hda_verb alc883_medion_md2_verbs[] = {
8790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8792
8793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8794
8795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8796 { } /* end */
8797};
8798
8799/* toggle speaker-output according to the hp-jack state */
4f5d1706 8800static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 8801{
a9fd4f3f 8802 struct alc_spec *spec = codec->spec;
272a527c 8803
a9fd4f3f
TI
8804 spec->autocfg.hp_pins[0] = 0x14;
8805 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
8806}
8807
ccc656ce 8808/* toggle speaker-output according to the hp-jack state */
c259249f
SA
8809#define alc883_targa_init_hook alc882_targa_init_hook
8810#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 8811
0c4cc443
HRK
8812static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8813{
8814 unsigned int present;
8815
d56757ab 8816 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
8817 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8818 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8819}
8820
4f5d1706 8821static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 8822{
a9fd4f3f
TI
8823 struct alc_spec *spec = codec->spec;
8824
8825 spec->autocfg.hp_pins[0] = 0x15;
8826 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
8827}
8828
8829static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8830{
a9fd4f3f 8831 alc_automute_amp(codec);
0c4cc443
HRK
8832 alc883_clevo_m720_mic_automute(codec);
8833}
8834
8835static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8836 unsigned int res)
8837{
0c4cc443 8838 switch (res >> 26) {
0c4cc443
HRK
8839 case ALC880_MIC_EVENT:
8840 alc883_clevo_m720_mic_automute(codec);
8841 break;
a9fd4f3f
TI
8842 default:
8843 alc_automute_amp_unsol_event(codec, res);
8844 break;
0c4cc443 8845 }
368c7a95
J
8846}
8847
fb97dc67 8848/* toggle speaker-output according to the hp-jack state */
4f5d1706 8849static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 8850{
a9fd4f3f 8851 struct alc_spec *spec = codec->spec;
fb97dc67 8852
a9fd4f3f
TI
8853 spec->autocfg.hp_pins[0] = 0x14;
8854 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
8855}
8856
4f5d1706 8857static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 8858{
a9fd4f3f 8859 struct alc_spec *spec = codec->spec;
189609ae 8860
a9fd4f3f
TI
8861 spec->autocfg.hp_pins[0] = 0x1b;
8862 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
8863}
8864
bc9f98a9
KY
8865static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8866{
864f92be 8867 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 8868
47fd830a
TI
8869 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8870 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8871}
8872
8873static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8874{
864f92be 8875 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 8876
47fd830a
TI
8877 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8878 HDA_AMP_MUTE, bits);
8879 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8880 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8881}
8882
8883static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8884 unsigned int res)
8885{
8886 if ((res >> 26) == ALC880_HP_EVENT)
8887 alc883_lenovo_101e_all_automute(codec);
8888 if ((res >> 26) == ALC880_FRONT_EVENT)
8889 alc883_lenovo_101e_ispeaker_automute(codec);
8890}
8891
676a9b53 8892/* toggle speaker-output according to the hp-jack state */
4f5d1706 8893static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 8894{
a9fd4f3f 8895 struct alc_spec *spec = codec->spec;
676a9b53 8896
a9fd4f3f
TI
8897 spec->autocfg.hp_pins[0] = 0x14;
8898 spec->autocfg.speaker_pins[0] = 0x15;
8899 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
8900}
8901
d1a991a6
KY
8902static struct hda_verb alc883_acer_eapd_verbs[] = {
8903 /* HP Pin: output 0 (0x0c) */
8904 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8905 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8906 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8907 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8909 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8910 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8911 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8912 /* eanable EAPD on medion laptop */
8913 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8914 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8915 /* enable unsolicited event */
8916 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8917 { }
8918};
8919
fc86f954
DK
8920static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8922 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8923 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8924 { } /* end */
8925};
8926
4f5d1706 8927static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 8928{
a9fd4f3f 8929 struct alc_spec *spec = codec->spec;
5795b9e6 8930
a9fd4f3f
TI
8931 spec->autocfg.hp_pins[0] = 0x1b;
8932 spec->autocfg.speaker_pins[0] = 0x14;
8933 spec->autocfg.speaker_pins[1] = 0x15;
8934 spec->autocfg.speaker_pins[2] = 0x16;
8935 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
8936}
8937
4f5d1706 8938static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 8939{
a9fd4f3f 8940 struct alc_spec *spec = codec->spec;
e2757d5e 8941
a9fd4f3f
TI
8942 spec->autocfg.hp_pins[0] = 0x1b;
8943 spec->autocfg.speaker_pins[0] = 0x14;
8944 spec->autocfg.speaker_pins[1] = 0x15;
8945 spec->autocfg.speaker_pins[2] = 0x16;
8946 spec->autocfg.speaker_pins[3] = 0x17;
8947 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
8948}
8949
4f5d1706 8950static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
8951{
8952 struct alc_spec *spec = codec->spec;
8953
8954 spec->autocfg.hp_pins[0] = 0x15;
8955 spec->autocfg.speaker_pins[0] = 0x14;
8956 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
8957}
8958
e2757d5e
KY
8959static struct hda_verb alc888_asus_m90v_verbs[] = {
8960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8961 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8962 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8963 /* enable unsolicited event */
8964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8965 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8966 { } /* end */
8967};
8968
4f5d1706 8969static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 8970{
a9fd4f3f 8971 struct alc_spec *spec = codec->spec;
e2757d5e 8972
a9fd4f3f
TI
8973 spec->autocfg.hp_pins[0] = 0x1b;
8974 spec->autocfg.speaker_pins[0] = 0x14;
8975 spec->autocfg.speaker_pins[1] = 0x15;
8976 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
8977 spec->ext_mic.pin = 0x18;
8978 spec->int_mic.pin = 0x19;
8979 spec->ext_mic.mux_idx = 0;
8980 spec->int_mic.mux_idx = 1;
8981 spec->auto_mic = 1;
e2757d5e
KY
8982}
8983
8984static struct hda_verb alc888_asus_eee1601_verbs[] = {
8985 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8988 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8989 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8990 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8991 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8992 /* enable unsolicited event */
8993 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8994 { } /* end */
8995};
8996
e2757d5e
KY
8997static void alc883_eee1601_inithook(struct hda_codec *codec)
8998{
a9fd4f3f
TI
8999 struct alc_spec *spec = codec->spec;
9000
9001 spec->autocfg.hp_pins[0] = 0x14;
9002 spec->autocfg.speaker_pins[0] = 0x1b;
9003 alc_automute_pin(codec);
e2757d5e
KY
9004}
9005
eb4c41d3
TS
9006static struct hda_verb alc889A_mb31_verbs[] = {
9007 /* Init rear pin (used as headphone output) */
9008 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9009 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9010 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9011 /* Init line pin (used as output in 4ch and 6ch mode) */
9012 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9013 /* Init line 2 pin (used as headphone out by default) */
9014 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9015 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9016 { } /* end */
9017};
9018
9019/* Mute speakers according to the headphone jack state */
9020static void alc889A_mb31_automute(struct hda_codec *codec)
9021{
9022 unsigned int present;
9023
9024 /* Mute only in 2ch or 4ch mode */
9025 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9026 == 0x00) {
864f92be 9027 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9028 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9029 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9030 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9031 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9032 }
9033}
9034
9035static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9036{
9037 if ((res >> 26) == ALC880_HP_EVENT)
9038 alc889A_mb31_automute(codec);
9039}
9040
4953550a 9041
cb53c626 9042#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9043#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9044#endif
9045
def319f9 9046/* pcm configuration: identical with ALC880 */
4953550a
TI
9047#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9048#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9049#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9050#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9051
9052static hda_nid_t alc883_slave_dig_outs[] = {
9053 ALC1200_DIGOUT_NID, 0,
9054};
9055
9056static hda_nid_t alc1200_slave_dig_outs[] = {
9057 ALC883_DIGOUT_NID, 0,
9058};
9c7f852e
TI
9059
9060/*
9061 * configuration and preset
9062 */
4953550a
TI
9063static const char *alc882_models[ALC882_MODEL_LAST] = {
9064 [ALC882_3ST_DIG] = "3stack-dig",
9065 [ALC882_6ST_DIG] = "6stack-dig",
9066 [ALC882_ARIMA] = "arima",
9067 [ALC882_W2JC] = "w2jc",
9068 [ALC882_TARGA] = "targa",
9069 [ALC882_ASUS_A7J] = "asus-a7j",
9070 [ALC882_ASUS_A7M] = "asus-a7m",
9071 [ALC885_MACPRO] = "macpro",
9072 [ALC885_MB5] = "mb5",
e458b1fa 9073 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9074 [ALC885_MBA21] = "mba21",
4953550a
TI
9075 [ALC885_MBP3] = "mbp3",
9076 [ALC885_IMAC24] = "imac24",
4b7e1803 9077 [ALC885_IMAC91] = "imac91",
4953550a 9078 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9079 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9080 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9081 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9082 [ALC883_TARGA_DIG] = "targa-dig",
9083 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9084 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9085 [ALC883_ACER] = "acer",
2880a867 9086 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9087 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9088 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9089 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9090 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9091 [ALC883_MEDION] = "medion",
272a527c 9092 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 9093 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9094 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9095 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9096 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9097 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9098 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9099 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9100 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9101 [ALC883_MITAC] = "mitac",
a65cc60f 9102 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9103 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9104 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9105 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9106 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9107 [ALC889A_INTEL] = "intel-alc889a",
9108 [ALC889_INTEL] = "intel-x58",
3ab90935 9109 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9110 [ALC889A_MB31] = "mb31",
3e1647c5 9111 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9112 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9113};
9114
4953550a
TI
9115static struct snd_pci_quirk alc882_cfg_tbl[] = {
9116 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9117
ac3e3741 9118 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9119 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9120 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9121 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9122 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9123 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9124 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9125 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9126 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9127 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9128 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9129 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9130 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9131 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9132 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9133 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9134 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9135 ALC888_ACER_ASPIRE_6530G),
cc374c47 9136 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9137 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9138 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9139 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9140 /* default Acer -- disabled as it causes more problems.
9141 * model=auto should work fine now
9142 */
9143 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9144
5795b9e6 9145 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9146
febe3375 9147 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9148 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9149 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9150 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9151 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9152 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9153
9154 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9155 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9156 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9157 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9158 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9159 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9160 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9161 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9162 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9163 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9164 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9165
9166 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9167 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9168 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9169 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9170 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9171 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9172 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9173 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9174 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9175
6f3bf657 9176 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9177 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9178 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9179 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9180 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9181 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9182 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9183 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9184 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9185 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9186 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9187 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9188 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9189 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9190 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9191 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9192 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9193 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
64a8be74 9194 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9195 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9196 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9197 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9198 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9199 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9200 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9201 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9202 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
f5fcc13c 9203 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9204 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9205
ac3e3741 9206 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
9207 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9208 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9209 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9210 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9211 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9212 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9213 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9214 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9215 ALC883_FUJITSU_PI2515),
bfb53037 9216 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9217 ALC888_FUJITSU_XA3530),
272a527c 9218 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9219 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9220 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9221 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9222 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9223 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9224 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9225 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9226 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9227
17bba1b7
J
9228 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9229 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9230 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9231 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9232 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9233 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
ac3e3741 9234 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e 9235
4953550a 9236 {}
f3cd3f5d
WF
9237};
9238
4953550a
TI
9239/* codec SSID table for Intel Mac */
9240static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9241 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9242 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9243 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9244 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9245 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9246 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9247 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9248 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9249 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9250 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9251 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9252 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
46ef6ec9
DC
9253 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9254 * so apparently no perfect solution yet
4953550a
TI
9255 */
9256 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9257 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9258 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9259 {} /* terminator */
b25c9da1
WF
9260};
9261
4953550a
TI
9262static struct alc_config_preset alc882_presets[] = {
9263 [ALC882_3ST_DIG] = {
9264 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9265 .init_verbs = { alc882_base_init_verbs,
9266 alc882_adc1_init_verbs },
4953550a
TI
9267 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9268 .dac_nids = alc882_dac_nids,
9269 .dig_out_nid = ALC882_DIGOUT_NID,
9270 .dig_in_nid = ALC882_DIGIN_NID,
9271 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9272 .channel_mode = alc882_ch_modes,
9273 .need_dac_fix = 1,
9274 .input_mux = &alc882_capture_source,
9275 },
9276 [ALC882_6ST_DIG] = {
9277 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9278 .init_verbs = { alc882_base_init_verbs,
9279 alc882_adc1_init_verbs },
4953550a
TI
9280 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9281 .dac_nids = alc882_dac_nids,
9282 .dig_out_nid = ALC882_DIGOUT_NID,
9283 .dig_in_nid = ALC882_DIGIN_NID,
9284 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9285 .channel_mode = alc882_sixstack_modes,
9286 .input_mux = &alc882_capture_source,
9287 },
9288 [ALC882_ARIMA] = {
9289 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9290 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9291 alc882_eapd_verbs },
4953550a
TI
9292 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9293 .dac_nids = alc882_dac_nids,
9294 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9295 .channel_mode = alc882_sixstack_modes,
9296 .input_mux = &alc882_capture_source,
9297 },
9298 [ALC882_W2JC] = {
9299 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9300 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9301 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9302 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9303 .dac_nids = alc882_dac_nids,
9304 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9305 .channel_mode = alc880_threestack_modes,
9306 .need_dac_fix = 1,
9307 .input_mux = &alc882_capture_source,
9308 .dig_out_nid = ALC882_DIGOUT_NID,
9309 },
76e6f5a9
RH
9310 [ALC885_MBA21] = {
9311 .mixers = { alc885_mba21_mixer },
9312 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9313 .num_dacs = 2,
9314 .dac_nids = alc882_dac_nids,
9315 .channel_mode = alc885_mba21_ch_modes,
9316 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9317 .input_mux = &alc882_capture_source,
9318 .unsol_event = alc_automute_amp_unsol_event,
9319 .setup = alc885_mba21_setup,
9320 .init_hook = alc_automute_amp,
9321 },
4953550a
TI
9322 [ALC885_MBP3] = {
9323 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9324 .init_verbs = { alc885_mbp3_init_verbs,
9325 alc880_gpio1_init_verbs },
be0ae923 9326 .num_dacs = 2,
4953550a 9327 .dac_nids = alc882_dac_nids,
be0ae923
TI
9328 .hp_nid = 0x04,
9329 .channel_mode = alc885_mbp_4ch_modes,
9330 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9331 .input_mux = &alc882_capture_source,
9332 .dig_out_nid = ALC882_DIGOUT_NID,
9333 .dig_in_nid = ALC882_DIGIN_NID,
9334 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9335 .setup = alc885_mbp3_setup,
9336 .init_hook = alc_automute_amp,
4953550a
TI
9337 },
9338 [ALC885_MB5] = {
9339 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9340 .init_verbs = { alc885_mb5_init_verbs,
9341 alc880_gpio1_init_verbs },
9342 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9343 .dac_nids = alc882_dac_nids,
9344 .channel_mode = alc885_mb5_6ch_modes,
9345 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9346 .input_mux = &mb5_capture_source,
9347 .dig_out_nid = ALC882_DIGOUT_NID,
9348 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9349 .unsol_event = alc_automute_amp_unsol_event,
9350 .setup = alc885_mb5_setup,
9351 .init_hook = alc_automute_amp,
4953550a 9352 },
e458b1fa
LY
9353 [ALC885_MACMINI3] = {
9354 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9355 .init_verbs = { alc885_macmini3_init_verbs,
9356 alc880_gpio1_init_verbs },
9357 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9358 .dac_nids = alc882_dac_nids,
9359 .channel_mode = alc885_macmini3_6ch_modes,
9360 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9361 .input_mux = &macmini3_capture_source,
9362 .dig_out_nid = ALC882_DIGOUT_NID,
9363 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9364 .unsol_event = alc_automute_amp_unsol_event,
9365 .setup = alc885_macmini3_setup,
9366 .init_hook = alc_automute_amp,
e458b1fa 9367 },
4953550a
TI
9368 [ALC885_MACPRO] = {
9369 .mixers = { alc882_macpro_mixer },
9370 .init_verbs = { alc882_macpro_init_verbs },
9371 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9372 .dac_nids = alc882_dac_nids,
9373 .dig_out_nid = ALC882_DIGOUT_NID,
9374 .dig_in_nid = ALC882_DIGIN_NID,
9375 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9376 .channel_mode = alc882_ch_modes,
9377 .input_mux = &alc882_capture_source,
9378 .init_hook = alc885_macpro_init_hook,
9379 },
9380 [ALC885_IMAC24] = {
9381 .mixers = { alc885_imac24_mixer },
9382 .init_verbs = { alc885_imac24_init_verbs },
9383 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9384 .dac_nids = alc882_dac_nids,
9385 .dig_out_nid = ALC882_DIGOUT_NID,
9386 .dig_in_nid = ALC882_DIGIN_NID,
9387 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9388 .channel_mode = alc882_ch_modes,
9389 .input_mux = &alc882_capture_source,
9390 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9391 .setup = alc885_imac24_setup,
4953550a
TI
9392 .init_hook = alc885_imac24_init_hook,
9393 },
4b7e1803
JM
9394 [ALC885_IMAC91] = {
9395 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
9396 .init_verbs = { alc885_imac91_init_verbs,
9397 alc880_gpio1_init_verbs },
9398 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9399 .dac_nids = alc882_dac_nids,
9400 .channel_mode = alc885_mbp_4ch_modes,
9401 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9402 .input_mux = &alc882_capture_source,
9403 .dig_out_nid = ALC882_DIGOUT_NID,
9404 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9405 .unsol_event = alc_automute_amp_unsol_event,
9406 .setup = alc885_imac91_setup,
9407 .init_hook = alc_automute_amp,
4b7e1803 9408 },
4953550a
TI
9409 [ALC882_TARGA] = {
9410 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9411 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9412 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9413 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9414 .dac_nids = alc882_dac_nids,
9415 .dig_out_nid = ALC882_DIGOUT_NID,
9416 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9417 .adc_nids = alc882_adc_nids,
9418 .capsrc_nids = alc882_capsrc_nids,
9419 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9420 .channel_mode = alc882_3ST_6ch_modes,
9421 .need_dac_fix = 1,
9422 .input_mux = &alc882_capture_source,
9423 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9424 .setup = alc882_targa_setup,
9425 .init_hook = alc882_targa_automute,
4953550a
TI
9426 },
9427 [ALC882_ASUS_A7J] = {
9428 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9429 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9430 alc882_asus_a7j_verbs},
4953550a
TI
9431 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9432 .dac_nids = alc882_dac_nids,
9433 .dig_out_nid = ALC882_DIGOUT_NID,
9434 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9435 .adc_nids = alc882_adc_nids,
9436 .capsrc_nids = alc882_capsrc_nids,
9437 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9438 .channel_mode = alc882_3ST_6ch_modes,
9439 .need_dac_fix = 1,
9440 .input_mux = &alc882_capture_source,
9441 },
9442 [ALC882_ASUS_A7M] = {
9443 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9444 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9445 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9446 alc882_asus_a7m_verbs },
9447 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9448 .dac_nids = alc882_dac_nids,
9449 .dig_out_nid = ALC882_DIGOUT_NID,
9450 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9451 .channel_mode = alc880_threestack_modes,
9452 .need_dac_fix = 1,
9453 .input_mux = &alc882_capture_source,
9454 },
9c7f852e
TI
9455 [ALC883_3ST_2ch_DIG] = {
9456 .mixers = { alc883_3ST_2ch_mixer },
9457 .init_verbs = { alc883_init_verbs },
9458 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9459 .dac_nids = alc883_dac_nids,
9460 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9461 .dig_in_nid = ALC883_DIGIN_NID,
9462 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9463 .channel_mode = alc883_3ST_2ch_modes,
9464 .input_mux = &alc883_capture_source,
9465 },
9466 [ALC883_3ST_6ch_DIG] = {
9467 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9468 .init_verbs = { alc883_init_verbs },
9469 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9470 .dac_nids = alc883_dac_nids,
9471 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9472 .dig_in_nid = ALC883_DIGIN_NID,
9473 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9474 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9475 .need_dac_fix = 1,
9c7f852e 9476 .input_mux = &alc883_capture_source,
f12ab1e0 9477 },
9c7f852e
TI
9478 [ALC883_3ST_6ch] = {
9479 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9480 .init_verbs = { alc883_init_verbs },
9481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9482 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9484 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9485 .need_dac_fix = 1,
9c7f852e 9486 .input_mux = &alc883_capture_source,
f12ab1e0 9487 },
17bba1b7
J
9488 [ALC883_3ST_6ch_INTEL] = {
9489 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9490 .init_verbs = { alc883_init_verbs },
9491 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9492 .dac_nids = alc883_dac_nids,
9493 .dig_out_nid = ALC883_DIGOUT_NID,
9494 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9495 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9496 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9497 .channel_mode = alc883_3ST_6ch_intel_modes,
9498 .need_dac_fix = 1,
9499 .input_mux = &alc883_3stack_6ch_intel,
9500 },
87a8c370
JK
9501 [ALC889A_INTEL] = {
9502 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9503 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9504 alc_hp15_unsol_verbs },
87a8c370
JK
9505 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9506 .dac_nids = alc883_dac_nids,
9507 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9508 .adc_nids = alc889_adc_nids,
9509 .dig_out_nid = ALC883_DIGOUT_NID,
9510 .dig_in_nid = ALC883_DIGIN_NID,
9511 .slave_dig_outs = alc883_slave_dig_outs,
9512 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9513 .channel_mode = alc889_8ch_intel_modes,
9514 .capsrc_nids = alc889_capsrc_nids,
9515 .input_mux = &alc889_capture_source,
4f5d1706
TI
9516 .setup = alc889_automute_setup,
9517 .init_hook = alc_automute_amp,
6732bd0d 9518 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9519 .need_dac_fix = 1,
9520 },
9521 [ALC889_INTEL] = {
9522 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9523 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9524 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9525 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9526 .dac_nids = alc883_dac_nids,
9527 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9528 .adc_nids = alc889_adc_nids,
9529 .dig_out_nid = ALC883_DIGOUT_NID,
9530 .dig_in_nid = ALC883_DIGIN_NID,
9531 .slave_dig_outs = alc883_slave_dig_outs,
9532 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9533 .channel_mode = alc889_8ch_intel_modes,
9534 .capsrc_nids = alc889_capsrc_nids,
9535 .input_mux = &alc889_capture_source,
4f5d1706 9536 .setup = alc889_automute_setup,
6732bd0d
WF
9537 .init_hook = alc889_intel_init_hook,
9538 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9539 .need_dac_fix = 1,
9540 },
9c7f852e
TI
9541 [ALC883_6ST_DIG] = {
9542 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9543 .init_verbs = { alc883_init_verbs },
9544 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9545 .dac_nids = alc883_dac_nids,
9546 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9547 .dig_in_nid = ALC883_DIGIN_NID,
9548 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9549 .channel_mode = alc883_sixstack_modes,
9550 .input_mux = &alc883_capture_source,
9551 },
ccc656ce 9552 [ALC883_TARGA_DIG] = {
c259249f 9553 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9554 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9555 alc883_targa_verbs},
ccc656ce
KY
9556 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9557 .dac_nids = alc883_dac_nids,
9558 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9559 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9560 .channel_mode = alc883_3ST_6ch_modes,
9561 .need_dac_fix = 1,
9562 .input_mux = &alc883_capture_source,
c259249f 9563 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9564 .setup = alc882_targa_setup,
9565 .init_hook = alc882_targa_automute,
ccc656ce
KY
9566 },
9567 [ALC883_TARGA_2ch_DIG] = {
c259249f 9568 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9569 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9570 alc883_targa_verbs},
ccc656ce
KY
9571 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9572 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9573 .adc_nids = alc883_adc_nids_alt,
9574 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9575 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9576 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9577 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9578 .channel_mode = alc883_3ST_2ch_modes,
9579 .input_mux = &alc883_capture_source,
c259249f 9580 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9581 .setup = alc882_targa_setup,
9582 .init_hook = alc882_targa_automute,
ccc656ce 9583 },
64a8be74 9584 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9585 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9586 alc883_chmode_mixer },
64a8be74 9587 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9588 alc883_targa_verbs },
64a8be74
DH
9589 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9590 .dac_nids = alc883_dac_nids,
9591 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9592 .adc_nids = alc883_adc_nids_rev,
9593 .capsrc_nids = alc883_capsrc_nids_rev,
9594 .dig_out_nid = ALC883_DIGOUT_NID,
9595 .dig_in_nid = ALC883_DIGIN_NID,
9596 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9597 .channel_mode = alc883_4ST_8ch_modes,
9598 .need_dac_fix = 1,
9599 .input_mux = &alc883_capture_source,
c259249f 9600 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9601 .setup = alc882_targa_setup,
9602 .init_hook = alc882_targa_automute,
64a8be74 9603 },
bab282b9 9604 [ALC883_ACER] = {
676a9b53 9605 .mixers = { alc883_base_mixer },
bab282b9
VA
9606 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9607 * and the headphone jack. Turn this on and rely on the
9608 * standard mute methods whenever the user wants to turn
9609 * these outputs off.
9610 */
9611 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9613 .dac_nids = alc883_dac_nids,
bab282b9
VA
9614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9615 .channel_mode = alc883_3ST_2ch_modes,
9616 .input_mux = &alc883_capture_source,
9617 },
2880a867 9618 [ALC883_ACER_ASPIRE] = {
676a9b53 9619 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 9620 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
9621 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9622 .dac_nids = alc883_dac_nids,
9623 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
9624 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9625 .channel_mode = alc883_3ST_2ch_modes,
9626 .input_mux = &alc883_capture_source,
a9fd4f3f 9627 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9628 .setup = alc883_acer_aspire_setup,
9629 .init_hook = alc_automute_amp,
d1a991a6 9630 },
5b2d1eca 9631 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 9632 .mixers = { alc888_base_mixer,
5b2d1eca
VP
9633 alc883_chmode_mixer },
9634 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9635 alc888_acer_aspire_4930g_verbs },
9636 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9637 .dac_nids = alc883_dac_nids,
9638 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9639 .adc_nids = alc883_adc_nids_rev,
9640 .capsrc_nids = alc883_capsrc_nids_rev,
9641 .dig_out_nid = ALC883_DIGOUT_NID,
9642 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9643 .channel_mode = alc883_3ST_6ch_modes,
9644 .need_dac_fix = 1,
973b8cb0 9645 .const_channel_count = 6,
5b2d1eca 9646 .num_mux_defs =
ef8ef5fb
VP
9647 ARRAY_SIZE(alc888_2_capture_sources),
9648 .input_mux = alc888_2_capture_sources,
d2fd4b09 9649 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9650 .setup = alc888_acer_aspire_4930g_setup,
9651 .init_hook = alc_automute_amp,
d2fd4b09
TV
9652 },
9653 [ALC888_ACER_ASPIRE_6530G] = {
9654 .mixers = { alc888_acer_aspire_6530_mixer },
9655 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9656 alc888_acer_aspire_6530g_verbs },
9657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9658 .dac_nids = alc883_dac_nids,
9659 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9660 .adc_nids = alc883_adc_nids_rev,
9661 .capsrc_nids = alc883_capsrc_nids_rev,
9662 .dig_out_nid = ALC883_DIGOUT_NID,
9663 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9664 .channel_mode = alc883_3ST_2ch_modes,
9665 .num_mux_defs =
9666 ARRAY_SIZE(alc888_2_capture_sources),
9667 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 9668 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9669 .setup = alc888_acer_aspire_6530g_setup,
9670 .init_hook = alc_automute_amp,
5b2d1eca 9671 },
3b315d70 9672 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 9673 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
9674 alc883_chmode_mixer },
9675 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
9676 alc889_acer_aspire_8930g_verbs,
9677 alc889_eapd_verbs},
3b315d70
HM
9678 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9679 .dac_nids = alc883_dac_nids,
018df418
HM
9680 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9681 .adc_nids = alc889_adc_nids,
9682 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
9683 .dig_out_nid = ALC883_DIGOUT_NID,
9684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9685 .channel_mode = alc883_3ST_6ch_modes,
9686 .need_dac_fix = 1,
9687 .const_channel_count = 6,
9688 .num_mux_defs =
018df418
HM
9689 ARRAY_SIZE(alc889_capture_sources),
9690 .input_mux = alc889_capture_sources,
3b315d70 9691 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9692 .setup = alc889_acer_aspire_8930g_setup,
9693 .init_hook = alc_automute_amp,
f5de24b0 9694#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 9695 .power_hook = alc_power_eapd,
f5de24b0 9696#endif
3b315d70 9697 },
fc86f954
DK
9698 [ALC888_ACER_ASPIRE_7730G] = {
9699 .mixers = { alc883_3ST_6ch_mixer,
9700 alc883_chmode_mixer },
9701 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9702 alc888_acer_aspire_7730G_verbs },
9703 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9704 .dac_nids = alc883_dac_nids,
9705 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9706 .adc_nids = alc883_adc_nids_rev,
9707 .capsrc_nids = alc883_capsrc_nids_rev,
9708 .dig_out_nid = ALC883_DIGOUT_NID,
9709 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9710 .channel_mode = alc883_3ST_6ch_modes,
9711 .need_dac_fix = 1,
9712 .const_channel_count = 6,
9713 .input_mux = &alc883_capture_source,
9714 .unsol_event = alc_automute_amp_unsol_event,
9715 .setup = alc888_acer_aspire_6530g_setup,
9716 .init_hook = alc_automute_amp,
9717 },
c07584c8
TD
9718 [ALC883_MEDION] = {
9719 .mixers = { alc883_fivestack_mixer,
9720 alc883_chmode_mixer },
9721 .init_verbs = { alc883_init_verbs,
b373bdeb 9722 alc883_medion_eapd_verbs },
c07584c8
TD
9723 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9724 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9725 .adc_nids = alc883_adc_nids_alt,
9726 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9727 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
9728 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9729 .channel_mode = alc883_sixstack_modes,
9730 .input_mux = &alc883_capture_source,
b373bdeb 9731 },
272a527c
KY
9732 [ALC883_MEDION_MD2] = {
9733 .mixers = { alc883_medion_md2_mixer},
9734 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9736 .dac_nids = alc883_dac_nids,
9737 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9739 .channel_mode = alc883_3ST_2ch_modes,
9740 .input_mux = &alc883_capture_source,
a9fd4f3f 9741 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9742 .setup = alc883_medion_md2_setup,
9743 .init_hook = alc_automute_amp,
ea1fb29a 9744 },
b373bdeb 9745 [ALC883_LAPTOP_EAPD] = {
676a9b53 9746 .mixers = { alc883_base_mixer },
b373bdeb
AN
9747 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9748 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9749 .dac_nids = alc883_dac_nids,
b373bdeb
AN
9750 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9751 .channel_mode = alc883_3ST_2ch_modes,
9752 .input_mux = &alc883_capture_source,
9753 },
a65cc60f 9754 [ALC883_CLEVO_M540R] = {
9755 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9756 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9757 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9758 .dac_nids = alc883_dac_nids,
9759 .dig_out_nid = ALC883_DIGOUT_NID,
9760 .dig_in_nid = ALC883_DIGIN_NID,
9761 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9762 .channel_mode = alc883_3ST_6ch_clevo_modes,
9763 .need_dac_fix = 1,
9764 .input_mux = &alc883_capture_source,
9765 /* This machine has the hardware HP auto-muting, thus
9766 * we need no software mute via unsol event
9767 */
9768 },
0c4cc443
HRK
9769 [ALC883_CLEVO_M720] = {
9770 .mixers = { alc883_clevo_m720_mixer },
9771 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
9772 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9773 .dac_nids = alc883_dac_nids,
9774 .dig_out_nid = ALC883_DIGOUT_NID,
9775 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9776 .channel_mode = alc883_3ST_2ch_modes,
9777 .input_mux = &alc883_capture_source,
0c4cc443 9778 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 9779 .setup = alc883_clevo_m720_setup,
a9fd4f3f 9780 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 9781 },
bc9f98a9
KY
9782 [ALC883_LENOVO_101E_2ch] = {
9783 .mixers = { alc883_lenovo_101e_2ch_mixer},
9784 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9786 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9787 .adc_nids = alc883_adc_nids_alt,
9788 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9789 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
9790 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9791 .channel_mode = alc883_3ST_2ch_modes,
9792 .input_mux = &alc883_lenovo_101e_capture_source,
9793 .unsol_event = alc883_lenovo_101e_unsol_event,
9794 .init_hook = alc883_lenovo_101e_all_automute,
9795 },
272a527c
KY
9796 [ALC883_LENOVO_NB0763] = {
9797 .mixers = { alc883_lenovo_nb0763_mixer },
9798 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9799 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9800 .dac_nids = alc883_dac_nids,
272a527c
KY
9801 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9802 .channel_mode = alc883_3ST_2ch_modes,
9803 .need_dac_fix = 1,
9804 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 9805 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9806 .setup = alc883_medion_md2_setup,
9807 .init_hook = alc_automute_amp,
272a527c
KY
9808 },
9809 [ALC888_LENOVO_MS7195_DIG] = {
9810 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9811 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9812 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9813 .dac_nids = alc883_dac_nids,
9814 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9815 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9816 .channel_mode = alc883_3ST_6ch_modes,
9817 .need_dac_fix = 1,
9818 .input_mux = &alc883_capture_source,
9819 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9820 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
9821 },
9822 [ALC883_HAIER_W66] = {
c259249f 9823 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
9824 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9825 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9826 .dac_nids = alc883_dac_nids,
9827 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
9828 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9829 .channel_mode = alc883_3ST_2ch_modes,
9830 .input_mux = &alc883_capture_source,
a9fd4f3f 9831 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9832 .setup = alc883_haier_w66_setup,
9833 .init_hook = alc_automute_amp,
eea6419e 9834 },
4723c022 9835 [ALC888_3ST_HP] = {
eea6419e 9836 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 9837 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
9838 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9839 .dac_nids = alc883_dac_nids,
4723c022
CM
9840 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9841 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
9842 .need_dac_fix = 1,
9843 .input_mux = &alc883_capture_source,
a9fd4f3f 9844 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9845 .setup = alc888_3st_hp_setup,
9846 .init_hook = alc_automute_amp,
8341de60 9847 },
5795b9e6 9848 [ALC888_6ST_DELL] = {
f24dbdc6 9849 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
9850 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9851 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9852 .dac_nids = alc883_dac_nids,
9853 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
9854 .dig_in_nid = ALC883_DIGIN_NID,
9855 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9856 .channel_mode = alc883_sixstack_modes,
9857 .input_mux = &alc883_capture_source,
a9fd4f3f 9858 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9859 .setup = alc888_6st_dell_setup,
9860 .init_hook = alc_automute_amp,
5795b9e6 9861 },
a8848bd6
AS
9862 [ALC883_MITAC] = {
9863 .mixers = { alc883_mitac_mixer },
9864 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9865 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9866 .dac_nids = alc883_dac_nids,
a8848bd6
AS
9867 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9868 .channel_mode = alc883_3ST_2ch_modes,
9869 .input_mux = &alc883_capture_source,
a9fd4f3f 9870 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9871 .setup = alc883_mitac_setup,
9872 .init_hook = alc_automute_amp,
a8848bd6 9873 },
fb97dc67
J
9874 [ALC883_FUJITSU_PI2515] = {
9875 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9876 .init_verbs = { alc883_init_verbs,
9877 alc883_2ch_fujitsu_pi2515_verbs},
9878 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9879 .dac_nids = alc883_dac_nids,
9880 .dig_out_nid = ALC883_DIGOUT_NID,
9881 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9882 .channel_mode = alc883_3ST_2ch_modes,
9883 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 9884 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9885 .setup = alc883_2ch_fujitsu_pi2515_setup,
9886 .init_hook = alc_automute_amp,
fb97dc67 9887 },
ef8ef5fb
VP
9888 [ALC888_FUJITSU_XA3530] = {
9889 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9890 .init_verbs = { alc883_init_verbs,
9891 alc888_fujitsu_xa3530_verbs },
9892 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9893 .dac_nids = alc883_dac_nids,
9894 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9895 .adc_nids = alc883_adc_nids_rev,
9896 .capsrc_nids = alc883_capsrc_nids_rev,
9897 .dig_out_nid = ALC883_DIGOUT_NID,
9898 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9899 .channel_mode = alc888_4ST_8ch_intel_modes,
9900 .num_mux_defs =
9901 ARRAY_SIZE(alc888_2_capture_sources),
9902 .input_mux = alc888_2_capture_sources,
a9fd4f3f 9903 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9904 .setup = alc888_fujitsu_xa3530_setup,
9905 .init_hook = alc_automute_amp,
ef8ef5fb 9906 },
e2757d5e
KY
9907 [ALC888_LENOVO_SKY] = {
9908 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9909 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9910 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9911 .dac_nids = alc883_dac_nids,
9912 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
9913 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9914 .channel_mode = alc883_sixstack_modes,
9915 .need_dac_fix = 1,
9916 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 9917 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9918 .setup = alc888_lenovo_sky_setup,
9919 .init_hook = alc_automute_amp,
e2757d5e
KY
9920 },
9921 [ALC888_ASUS_M90V] = {
9922 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9923 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9924 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9925 .dac_nids = alc883_dac_nids,
9926 .dig_out_nid = ALC883_DIGOUT_NID,
9927 .dig_in_nid = ALC883_DIGIN_NID,
9928 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9929 .channel_mode = alc883_3ST_6ch_modes,
9930 .need_dac_fix = 1,
9931 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
9932 .unsol_event = alc_sku_unsol_event,
9933 .setup = alc883_mode2_setup,
9934 .init_hook = alc_inithook,
e2757d5e
KY
9935 },
9936 [ALC888_ASUS_EEE1601] = {
9937 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 9938 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
9939 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9940 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9941 .dac_nids = alc883_dac_nids,
9942 .dig_out_nid = ALC883_DIGOUT_NID,
9943 .dig_in_nid = ALC883_DIGIN_NID,
9944 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9945 .channel_mode = alc883_3ST_2ch_modes,
9946 .need_dac_fix = 1,
9947 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 9948 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
9949 .init_hook = alc883_eee1601_inithook,
9950 },
3ab90935
WF
9951 [ALC1200_ASUS_P5Q] = {
9952 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9953 .init_verbs = { alc883_init_verbs },
9954 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9955 .dac_nids = alc883_dac_nids,
9956 .dig_out_nid = ALC1200_DIGOUT_NID,
9957 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 9958 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
9959 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9960 .channel_mode = alc883_sixstack_modes,
9961 .input_mux = &alc883_capture_source,
9962 },
eb4c41d3
TS
9963 [ALC889A_MB31] = {
9964 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9965 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9966 alc880_gpio1_init_verbs },
9967 .adc_nids = alc883_adc_nids,
9968 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 9969 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
9970 .dac_nids = alc883_dac_nids,
9971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9972 .channel_mode = alc889A_mb31_6ch_modes,
9973 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9974 .input_mux = &alc889A_mb31_capture_source,
9975 .dig_out_nid = ALC883_DIGOUT_NID,
9976 .unsol_event = alc889A_mb31_unsol_event,
9977 .init_hook = alc889A_mb31_automute,
9978 },
3e1647c5
GG
9979 [ALC883_SONY_VAIO_TT] = {
9980 .mixers = { alc883_vaiott_mixer },
9981 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9982 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9983 .dac_nids = alc883_dac_nids,
9984 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9985 .channel_mode = alc883_3ST_2ch_modes,
9986 .input_mux = &alc883_capture_source,
9987 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9988 .setup = alc883_vaiott_setup,
9989 .init_hook = alc_automute_amp,
3e1647c5 9990 },
9c7f852e
TI
9991};
9992
9993
4953550a
TI
9994/*
9995 * Pin config fixes
9996 */
9997enum {
9998 PINFIX_ABIT_AW9D_MAX
9999};
10000
10001static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10002 { 0x15, 0x01080104 }, /* side */
10003 { 0x16, 0x01011012 }, /* rear */
10004 { 0x17, 0x01016011 }, /* clfe */
10005 { }
10006};
10007
f8f25ba3
TI
10008static const struct alc_fixup alc882_fixups[] = {
10009 [PINFIX_ABIT_AW9D_MAX] = {
10010 .pins = alc882_abit_aw9d_pinfix
10011 },
4953550a
TI
10012};
10013
f8f25ba3 10014static struct snd_pci_quirk alc882_fixup_tbl[] = {
4953550a
TI
10015 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10016 {}
10017};
10018
9c7f852e
TI
10019/*
10020 * BIOS auto configuration
10021 */
05f5f477
TI
10022static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10023 const struct auto_pin_cfg *cfg)
10024{
10025 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10026}
10027
4953550a 10028static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e
TI
10029 hda_nid_t nid, int pin_type,
10030 int dac_idx)
10031{
10032 /* set as output */
10033 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
10034 int idx;
10035
f6c7e546 10036 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
10037 if (spec->multiout.dac_nids[dac_idx] == 0x25)
10038 idx = 4;
10039 else
10040 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
10041 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10042
10043}
10044
4953550a 10045static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10046{
10047 struct alc_spec *spec = codec->spec;
10048 int i;
10049
10050 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10051 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10052 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10053 if (nid)
4953550a 10054 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 10055 i);
9c7f852e
TI
10056 }
10057}
10058
4953550a 10059static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10060{
10061 struct alc_spec *spec = codec->spec;
10062 hda_nid_t pin;
10063
eb06ed8f 10064 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
10065 if (pin) /* connect to front */
10066 /* use dac 0 */
4953550a 10067 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
10068 pin = spec->autocfg.speaker_pins[0];
10069 if (pin)
4953550a 10070 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
10071}
10072
4953550a 10073static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10074{
10075 struct alc_spec *spec = codec->spec;
10076 int i;
10077
10078 for (i = 0; i < AUTO_PIN_LAST; i++) {
10079 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10080 if (!nid)
10081 continue;
0d971c9f 10082 alc_set_input_pin(codec, nid, i);
4953550a
TI
10083 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10084 snd_hda_codec_write(codec, nid, 0,
10085 AC_VERB_SET_AMP_GAIN_MUTE,
10086 AMP_OUT_MUTE);
10087 }
10088}
10089
10090static void alc882_auto_init_input_src(struct hda_codec *codec)
10091{
10092 struct alc_spec *spec = codec->spec;
10093 int c;
10094
10095 for (c = 0; c < spec->num_adc_nids; c++) {
10096 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10097 hda_nid_t nid = spec->capsrc_nids[c];
10098 unsigned int mux_idx;
10099 const struct hda_input_mux *imux;
10100 int conns, mute, idx, item;
10101
10102 conns = snd_hda_get_connections(codec, nid, conn_list,
10103 ARRAY_SIZE(conn_list));
10104 if (conns < 0)
10105 continue;
10106 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10107 imux = &spec->input_mux[mux_idx];
10108 for (idx = 0; idx < conns; idx++) {
10109 /* if the current connection is the selected one,
10110 * unmute it as default - otherwise mute it
10111 */
10112 mute = AMP_IN_MUTE(idx);
10113 for (item = 0; item < imux->num_items; item++) {
10114 if (imux->items[item].index == idx) {
10115 if (spec->cur_mux[c] == item)
10116 mute = AMP_IN_UNMUTE(idx);
10117 break;
10118 }
10119 }
10120 /* check if we have a selector or mixer
10121 * we could check for the widget type instead, but
10122 * just check for Amp-In presence (in case of mixer
10123 * without amp-in there is something wrong, this
10124 * function shouldn't be used or capsrc nid is wrong)
10125 */
10126 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10127 snd_hda_codec_write(codec, nid, 0,
10128 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10129 mute);
10130 else if (mute != AMP_IN_MUTE(idx))
10131 snd_hda_codec_write(codec, nid, 0,
10132 AC_VERB_SET_CONNECT_SEL,
10133 idx);
9c7f852e
TI
10134 }
10135 }
10136}
10137
4953550a
TI
10138/* add mic boosts if needed */
10139static int alc_auto_add_mic_boost(struct hda_codec *codec)
10140{
10141 struct alc_spec *spec = codec->spec;
10142 int err;
10143 hda_nid_t nid;
10144
10145 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10146 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10147 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10148 "Mic Boost",
10149 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10150 if (err < 0)
10151 return err;
10152 }
10153 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10154 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10155 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10156 "Front Mic Boost",
10157 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10158 if (err < 0)
10159 return err;
10160 }
10161 return 0;
10162}
f511b01c 10163
9c7f852e 10164/* almost identical with ALC880 parser... */
4953550a 10165static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10166{
10167 struct alc_spec *spec = codec->spec;
05f5f477
TI
10168 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10169 int i, err;
9c7f852e 10170
05f5f477
TI
10171 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10172 alc882_ignore);
9c7f852e
TI
10173 if (err < 0)
10174 return err;
05f5f477
TI
10175 if (!spec->autocfg.line_outs)
10176 return 0; /* can't find valid BIOS pin config */
776e184e 10177
05f5f477
TI
10178 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10179 if (err < 0)
10180 return err;
10181 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10182 if (err < 0)
10183 return err;
10184 err = alc880_auto_create_extra_out(spec,
10185 spec->autocfg.speaker_pins[0],
10186 "Speaker");
10187 if (err < 0)
10188 return err;
10189 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10190 "Headphone");
10191 if (err < 0)
10192 return err;
10193 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10194 if (err < 0)
10195 return err;
10196
05f5f477
TI
10197 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10198
10199 /* check multiple SPDIF-out (for recent codecs) */
10200 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10201 hda_nid_t dig_nid;
10202 err = snd_hda_get_connections(codec,
10203 spec->autocfg.dig_out_pins[i],
10204 &dig_nid, 1);
10205 if (err < 0)
10206 continue;
10207 if (!i)
10208 spec->multiout.dig_out_nid = dig_nid;
10209 else {
10210 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 10211 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
05f5f477 10212 break;
71121d9f 10213 spec->slave_dig_outs[i - 1] = dig_nid;
05f5f477
TI
10214 }
10215 }
10216 if (spec->autocfg.dig_in_pin)
10217 spec->dig_in_nid = ALC880_DIGIN_NID;
10218
10219 if (spec->kctls.list)
10220 add_mixer(spec, spec->kctls.list);
10221
10222 add_verb(spec, alc883_auto_init_verbs);
4953550a 10223 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10224 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10225 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10226
05f5f477
TI
10227 spec->num_mux_defs = 1;
10228 spec->input_mux = &spec->private_imux[0];
10229
6227cdce 10230 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10231
10232 err = alc_auto_add_mic_boost(codec);
10233 if (err < 0)
10234 return err;
61b9b9b1 10235
776e184e 10236 return 1; /* config found */
9c7f852e
TI
10237}
10238
10239/* additional initialization for auto-configuration model */
4953550a 10240static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10241{
f6c7e546 10242 struct alc_spec *spec = codec->spec;
4953550a
TI
10243 alc882_auto_init_multi_out(codec);
10244 alc882_auto_init_hp_out(codec);
10245 alc882_auto_init_analog_input(codec);
10246 alc882_auto_init_input_src(codec);
f6c7e546 10247 if (spec->unsol_event)
7fb0d78f 10248 alc_inithook(codec);
9c7f852e
TI
10249}
10250
4953550a 10251static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10252{
10253 struct alc_spec *spec;
10254 int err, board_config;
10255
10256 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10257 if (spec == NULL)
10258 return -ENOMEM;
10259
10260 codec->spec = spec;
10261
4953550a
TI
10262 switch (codec->vendor_id) {
10263 case 0x10ec0882:
10264 case 0x10ec0885:
10265 break;
10266 default:
10267 /* ALC883 and variants */
10268 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10269 break;
10270 }
2c3bf9ab 10271
4953550a
TI
10272 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10273 alc882_models,
10274 alc882_cfg_tbl);
10275
10276 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10277 board_config = snd_hda_check_board_codec_sid_config(codec,
10278 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10279
10280 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10281 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10282 codec->chip_name);
10283 board_config = ALC882_AUTO;
9c7f852e
TI
10284 }
10285
f8f25ba3 10286 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
4953550a
TI
10287
10288 if (board_config == ALC882_AUTO) {
9c7f852e 10289 /* automatic parse from the BIOS config */
4953550a 10290 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10291 if (err < 0) {
10292 alc_free(codec);
10293 return err;
f12ab1e0 10294 } else if (!err) {
9c7f852e
TI
10295 printk(KERN_INFO
10296 "hda_codec: Cannot set up configuration "
10297 "from BIOS. Using base mode...\n");
4953550a 10298 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10299 }
10300 }
10301
680cd536
KK
10302 err = snd_hda_attach_beep_device(codec, 0x1);
10303 if (err < 0) {
10304 alc_free(codec);
10305 return err;
10306 }
10307
4953550a 10308 if (board_config != ALC882_AUTO)
e9c364c0 10309 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10310
4953550a
TI
10311 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10312 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10313 /* FIXME: setup DAC5 */
10314 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10315 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10316
10317 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10318 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10319
10320 if (codec->vendor_id == 0x10ec0888)
4a79ba34 10321 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
4953550a
TI
10322
10323 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10324 int i, j;
4953550a
TI
10325 spec->num_adc_nids = 0;
10326 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10327 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10328 hda_nid_t cap;
d11f74c6 10329 hda_nid_t items[16];
4953550a
TI
10330 hda_nid_t nid = alc882_adc_nids[i];
10331 unsigned int wcap = get_wcaps(codec, nid);
10332 /* get type */
a22d543a 10333 wcap = get_wcaps_type(wcap);
4953550a
TI
10334 if (wcap != AC_WID_AUD_IN)
10335 continue;
10336 spec->private_adc_nids[spec->num_adc_nids] = nid;
10337 err = snd_hda_get_connections(codec, nid, &cap, 1);
10338 if (err < 0)
10339 continue;
d11f74c6
TI
10340 err = snd_hda_get_connections(codec, cap, items,
10341 ARRAY_SIZE(items));
10342 if (err < 0)
10343 continue;
10344 for (j = 0; j < imux->num_items; j++)
10345 if (imux->items[j].index >= err)
10346 break;
10347 if (j < imux->num_items)
10348 continue;
4953550a
TI
10349 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10350 spec->num_adc_nids++;
61b9b9b1 10351 }
4953550a
TI
10352 spec->adc_nids = spec->private_adc_nids;
10353 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10354 }
10355
b59bdf3b 10356 set_capture_mixer(codec);
45bdd1c1 10357 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10358
2134ea4f
TI
10359 spec->vmaster_nid = 0x0c;
10360
9c7f852e 10361 codec->patch_ops = alc_patch_ops;
4953550a
TI
10362 if (board_config == ALC882_AUTO)
10363 spec->init_hook = alc882_auto_init;
cb53c626
TI
10364#ifdef CONFIG_SND_HDA_POWER_SAVE
10365 if (!spec->loopback.amplist)
4953550a 10366 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10367#endif
9c7f852e
TI
10368
10369 return 0;
10370}
10371
4953550a 10372
9c7f852e
TI
10373/*
10374 * ALC262 support
10375 */
10376
10377#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10378#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10379
10380#define alc262_dac_nids alc260_dac_nids
10381#define alc262_adc_nids alc882_adc_nids
10382#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10383#define alc262_capsrc_nids alc882_capsrc_nids
10384#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10385
10386#define alc262_modes alc260_modes
10387#define alc262_capture_source alc882_capture_source
10388
4e555fe5
KY
10389static hda_nid_t alc262_dmic_adc_nids[1] = {
10390 /* ADC0 */
10391 0x09
10392};
10393
10394static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10395
9c7f852e
TI
10396static struct snd_kcontrol_new alc262_base_mixer[] = {
10397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10398 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10405 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10408 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10409 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10410 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10411 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10412 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10413 { } /* end */
10414};
10415
ce875f07
TI
10416/* update HP, line and mono-out pins according to the master switch */
10417static void alc262_hp_master_update(struct hda_codec *codec)
10418{
10419 struct alc_spec *spec = codec->spec;
10420 int val = spec->master_sw;
10421
10422 /* HP & line-out */
10423 snd_hda_codec_write_cache(codec, 0x1b, 0,
10424 AC_VERB_SET_PIN_WIDGET_CONTROL,
10425 val ? PIN_HP : 0);
10426 snd_hda_codec_write_cache(codec, 0x15, 0,
10427 AC_VERB_SET_PIN_WIDGET_CONTROL,
10428 val ? PIN_HP : 0);
10429 /* mono (speaker) depending on the HP jack sense */
10430 val = val && !spec->jack_present;
10431 snd_hda_codec_write_cache(codec, 0x16, 0,
10432 AC_VERB_SET_PIN_WIDGET_CONTROL,
10433 val ? PIN_OUT : 0);
10434}
10435
10436static void alc262_hp_bpc_automute(struct hda_codec *codec)
10437{
10438 struct alc_spec *spec = codec->spec;
864f92be
WF
10439
10440 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10441 alc262_hp_master_update(codec);
10442}
10443
10444static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10445{
10446 if ((res >> 26) != ALC880_HP_EVENT)
10447 return;
10448 alc262_hp_bpc_automute(codec);
10449}
10450
10451static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10452{
10453 struct alc_spec *spec = codec->spec;
864f92be
WF
10454
10455 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10456 alc262_hp_master_update(codec);
10457}
10458
10459static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10460 unsigned int res)
10461{
10462 if ((res >> 26) != ALC880_HP_EVENT)
10463 return;
10464 alc262_hp_wildwest_automute(codec);
10465}
10466
b72519b5 10467#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10468
10469static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10470 struct snd_ctl_elem_value *ucontrol)
10471{
10472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10473 struct alc_spec *spec = codec->spec;
10474 int val = !!*ucontrol->value.integer.value;
10475
10476 if (val == spec->master_sw)
10477 return 0;
10478 spec->master_sw = val;
10479 alc262_hp_master_update(codec);
10480 return 1;
10481}
10482
b72519b5
TI
10483#define ALC262_HP_MASTER_SWITCH \
10484 { \
10485 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10486 .name = "Master Playback Switch", \
10487 .info = snd_ctl_boolean_mono_info, \
10488 .get = alc262_hp_master_sw_get, \
10489 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10490 }, \
10491 { \
10492 .iface = NID_MAPPING, \
10493 .name = "Master Playback Switch", \
10494 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10495 }
10496
5b0cb1d8 10497
9c7f852e 10498static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10499 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10501 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10503 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10504 HDA_OUTPUT),
10505 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10506 HDA_OUTPUT),
9c7f852e
TI
10507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10509 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10511 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10512 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10513 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10514 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10515 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10516 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10517 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10518 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10519 { } /* end */
10520};
10521
cd7509a4 10522static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10523 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10524 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10525 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10526 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10528 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10529 HDA_OUTPUT),
10530 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10531 HDA_OUTPUT),
cd7509a4
KY
10532 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10533 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10534 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10535 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10536 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10539 { } /* end */
10540};
10541
10542static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10543 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10544 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10545 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10546 { } /* end */
10547};
10548
66d2a9d6 10549/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10550static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10551{
10552 struct alc_spec *spec = codec->spec;
66d2a9d6 10553
a9fd4f3f 10554 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10555 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10556}
10557
66d2a9d6 10558static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10559 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10560 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10561 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10564 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10565 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10566 { } /* end */
10567};
10568
10569static struct hda_verb alc262_hp_t5735_verbs[] = {
10570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10572
10573 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10574 { }
10575};
10576
8c427226 10577static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
10578 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
10580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
10582 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10583 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10584 { } /* end */
10585};
10586
10587static struct hda_verb alc262_hp_rp5700_verbs[] = {
10588 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10589 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10590 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10592 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10593 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10595 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10597 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10598 {}
10599};
10600
10601static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10602 .num_items = 1,
10603 .items = {
10604 { "Line", 0x1 },
10605 },
10606};
10607
42171c17
TI
10608/* bind hp and internal speaker mute (with plug check) as master switch */
10609static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 10610{
42171c17
TI
10611 struct alc_spec *spec = codec->spec;
10612 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10613 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10614 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10615 unsigned int mute;
0724ea2a 10616
42171c17
TI
10617 /* HP */
10618 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10619 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10620 HDA_AMP_MUTE, mute);
10621 /* mute internal speaker per jack sense */
10622 if (spec->jack_present)
10623 mute = HDA_AMP_MUTE;
10624 if (line_nid)
10625 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10626 HDA_AMP_MUTE, mute);
10627 if (speaker_nid && speaker_nid != line_nid)
10628 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 10629 HDA_AMP_MUTE, mute);
42171c17
TI
10630}
10631
10632#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10633
10634static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10635 struct snd_ctl_elem_value *ucontrol)
10636{
10637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10638 struct alc_spec *spec = codec->spec;
10639 int val = !!*ucontrol->value.integer.value;
10640
10641 if (val == spec->master_sw)
10642 return 0;
10643 spec->master_sw = val;
10644 alc262_hippo_master_update(codec);
10645 return 1;
10646}
10647
10648#define ALC262_HIPPO_MASTER_SWITCH \
10649 { \
10650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10651 .name = "Master Playback Switch", \
10652 .info = snd_ctl_boolean_mono_info, \
10653 .get = alc262_hippo_master_sw_get, \
10654 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
10655 }, \
10656 { \
10657 .iface = NID_MAPPING, \
10658 .name = "Master Playback Switch", \
10659 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10660 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 10661 }
42171c17
TI
10662
10663static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10664 ALC262_HIPPO_MASTER_SWITCH,
10665 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10673 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10674 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10675 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10676 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10677 { } /* end */
10678};
10679
10680static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10681 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10682 ALC262_HIPPO_MASTER_SWITCH,
10683 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10684 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10685 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10686 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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
10696/* mute/unmute internal speaker according to the hp jack and mute state */
10697static void alc262_hippo_automute(struct hda_codec *codec)
10698{
10699 struct alc_spec *spec = codec->spec;
10700 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 10701
864f92be 10702 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 10703 alc262_hippo_master_update(codec);
0724ea2a 10704}
5b31954e 10705
42171c17
TI
10706static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10707{
10708 if ((res >> 26) != ALC880_HP_EVENT)
10709 return;
10710 alc262_hippo_automute(codec);
10711}
10712
4f5d1706 10713static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
10714{
10715 struct alc_spec *spec = codec->spec;
10716
10717 spec->autocfg.hp_pins[0] = 0x15;
10718 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10719}
10720
4f5d1706 10721static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
10722{
10723 struct alc_spec *spec = codec->spec;
10724
10725 spec->autocfg.hp_pins[0] = 0x1b;
10726 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10727}
10728
10729
272a527c 10730static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 10731 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 10732 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
10733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10735 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10736 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10737 { } /* end */
10738};
10739
83c34218 10740static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
10741 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10742 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
10743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10746 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10747 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10748 { } /* end */
10749};
272a527c 10750
ba340e82
TV
10751static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10752 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10753 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10754 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10755 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10757 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10760 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10761 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10762 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10763 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10764 { } /* end */
10765};
10766
10767static struct hda_verb alc262_tyan_verbs[] = {
10768 /* Headphone automute */
10769 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10772
10773 /* P11 AUX_IN, white 4-pin connector */
10774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10775 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10776 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10777 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10778
10779 {}
10780};
10781
10782/* unsolicited event for HP jack sensing */
4f5d1706 10783static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 10784{
a9fd4f3f 10785 struct alc_spec *spec = codec->spec;
ba340e82 10786
a9fd4f3f
TI
10787 spec->autocfg.hp_pins[0] = 0x1b;
10788 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
10789}
10790
ba340e82 10791
9c7f852e
TI
10792#define alc262_capture_mixer alc882_capture_mixer
10793#define alc262_capture_alt_mixer alc882_capture_alt_mixer
10794
10795/*
10796 * generic initialization of ADC, input mixers and output mixers
10797 */
10798static struct hda_verb alc262_init_verbs[] = {
10799 /*
10800 * Unmute ADC0-2 and set the default input to mic-in
10801 */
10802 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10803 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10804 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10806 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10807 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10808
cb53c626 10809 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10810 * mixer widget
f12ab1e0
TI
10811 * Note: PASD motherboards uses the Line In 2 as the input for
10812 * front panel mic (mic 2)
9c7f852e
TI
10813 */
10814 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10816 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10817 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10818 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10819 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
10820
10821 /*
df694daa
KY
10822 * Set up output mixers (0x0c - 0x0e)
10823 */
10824 /* set vol=0 to output mixers */
10825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10826 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10827 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10828 /* set up input amps for analog loopback */
10829 /* Amp Indices: DAC = 0, mixer = 1 */
10830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10832 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10833 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10834 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10835 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10836
10837 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10838 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10839 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10840 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10842 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10843
10844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10845 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10846 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10847 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10848 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 10849
df694daa
KY
10850 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10851 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 10852
df694daa
KY
10853 /* FIXME: use matrix-type input source selection */
10854 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10855 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10859 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10860 /* Input mixer2 */
10861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10863 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10864 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10865 /* Input mixer3 */
10866 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 10869 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
10870
10871 { }
10872};
1da177e4 10873
4e555fe5
KY
10874static struct hda_verb alc262_eapd_verbs[] = {
10875 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10876 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10877 { }
10878};
10879
ccc656ce
KY
10880static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10881 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10882 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10883 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10884
10885 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10887 {}
10888};
10889
272a527c
KY
10890static struct hda_verb alc262_sony_unsol_verbs[] = {
10891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10892 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10893 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10894
10895 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 10897 {}
272a527c
KY
10898};
10899
4e555fe5
KY
10900static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10901 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10902 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
10906 { } /* end */
10907};
10908
10909static struct hda_verb alc262_toshiba_s06_verbs[] = {
10910 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10913 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10914 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10915 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10916 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10917 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10918 {}
10919};
10920
4f5d1706 10921static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 10922{
a9fd4f3f
TI
10923 struct alc_spec *spec = codec->spec;
10924
10925 spec->autocfg.hp_pins[0] = 0x15;
10926 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
10927 spec->ext_mic.pin = 0x18;
10928 spec->ext_mic.mux_idx = 0;
10929 spec->int_mic.pin = 0x12;
10930 spec->int_mic.mux_idx = 9;
10931 spec->auto_mic = 1;
4e555fe5
KY
10932}
10933
e8f9ae2a
PT
10934/*
10935 * nec model
10936 * 0x15 = headphone
10937 * 0x16 = internal speaker
10938 * 0x18 = external mic
10939 */
10940
10941static struct snd_kcontrol_new alc262_nec_mixer[] = {
10942 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10943 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10944
10945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10946 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10947 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10948
10949 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10950 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10951 { } /* end */
10952};
10953
10954static struct hda_verb alc262_nec_verbs[] = {
10955 /* Unmute Speaker */
10956 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10957
10958 /* Headphone */
10959 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10960 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10961
10962 /* External mic to headphone */
10963 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10964 /* External mic to speaker */
10965 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10966 {}
10967};
10968
834be88d
TI
10969/*
10970 * fujitsu model
5d9fab2d
TV
10971 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10972 * 0x1b = port replicator headphone out
834be88d
TI
10973 */
10974
10975#define ALC_HP_EVENT 0x37
10976
10977static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10978 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10979 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
10980 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
10982 {}
10983};
10984
0e31daf7
J
10985static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10986 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10987 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10988 {}
10989};
10990
e2595322
DC
10991static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
10992 /* Front Mic pin: input vref at 50% */
10993 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10994 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10995 {}
10996};
10997
834be88d 10998static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 10999 .num_items = 3,
834be88d
TI
11000 .items = {
11001 { "Mic", 0x0 },
39d3ed38 11002 { "Int Mic", 0x1 },
834be88d
TI
11003 { "CD", 0x4 },
11004 },
11005};
11006
9c7f852e
TI
11007static struct hda_input_mux alc262_HP_capture_source = {
11008 .num_items = 5,
11009 .items = {
11010 { "Mic", 0x0 },
accbe498 11011 { "Front Mic", 0x1 },
9c7f852e
TI
11012 { "Line", 0x2 },
11013 { "CD", 0x4 },
11014 { "AUX IN", 0x6 },
11015 },
11016};
11017
accbe498 11018static struct hda_input_mux alc262_HP_D7000_capture_source = {
11019 .num_items = 4,
11020 .items = {
11021 { "Mic", 0x0 },
11022 { "Front Mic", 0x2 },
11023 { "Line", 0x1 },
11024 { "CD", 0x4 },
11025 },
11026};
11027
ebc7a406 11028/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11029static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11030{
11031 struct alc_spec *spec = codec->spec;
11032 unsigned int mute;
11033
f12ab1e0 11034 if (force || !spec->sense_updated) {
864f92be
WF
11035 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11036 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11037 spec->sense_updated = 1;
11038 }
ebc7a406
TI
11039 /* unmute internal speaker only if both HPs are unplugged and
11040 * master switch is on
11041 */
11042 if (spec->jack_present)
11043 mute = HDA_AMP_MUTE;
11044 else
834be88d 11045 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11046 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11047 HDA_AMP_MUTE, mute);
834be88d
TI
11048}
11049
11050/* unsolicited event for HP jack sensing */
11051static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11052 unsigned int res)
11053{
11054 if ((res >> 26) != ALC_HP_EVENT)
11055 return;
11056 alc262_fujitsu_automute(codec, 1);
11057}
11058
ebc7a406
TI
11059static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11060{
11061 alc262_fujitsu_automute(codec, 1);
11062}
11063
834be88d 11064/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11065static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11066 .ops = &snd_hda_bind_vol,
11067 .values = {
11068 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11069 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11070 0
11071 },
11072};
834be88d 11073
0e31daf7
J
11074/* mute/unmute internal speaker according to the hp jack and mute state */
11075static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11076{
11077 struct alc_spec *spec = codec->spec;
11078 unsigned int mute;
11079
11080 if (force || !spec->sense_updated) {
864f92be 11081 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11082 spec->sense_updated = 1;
11083 }
11084 if (spec->jack_present) {
11085 /* mute internal speaker */
11086 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11087 HDA_AMP_MUTE, HDA_AMP_MUTE);
11088 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11089 HDA_AMP_MUTE, HDA_AMP_MUTE);
11090 } else {
11091 /* unmute internal speaker if necessary */
11092 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11093 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11094 HDA_AMP_MUTE, mute);
11095 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11096 HDA_AMP_MUTE, mute);
11097 }
11098}
11099
11100/* unsolicited event for HP jack sensing */
11101static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11102 unsigned int res)
11103{
11104 if ((res >> 26) != ALC_HP_EVENT)
11105 return;
11106 alc262_lenovo_3000_automute(codec, 1);
11107}
11108
8de56b7d
TI
11109static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11110 int dir, int idx, long *valp)
11111{
11112 int i, change = 0;
11113
11114 for (i = 0; i < 2; i++, valp++)
11115 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11116 HDA_AMP_MUTE,
11117 *valp ? 0 : HDA_AMP_MUTE);
11118 return change;
11119}
11120
834be88d
TI
11121/* bind hp and internal speaker mute (with plug check) */
11122static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11123 struct snd_ctl_elem_value *ucontrol)
11124{
11125 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11126 long *valp = ucontrol->value.integer.value;
11127 int change;
11128
8de56b7d
TI
11129 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11130 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11131 if (change)
11132 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11133 return change;
11134}
11135
11136static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11137 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11138 {
11139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11140 .name = "Master Playback Switch",
5e26dfd0 11141 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11142 .info = snd_hda_mixer_amp_switch_info,
11143 .get = snd_hda_mixer_amp_switch_get,
11144 .put = alc262_fujitsu_master_sw_put,
11145 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11146 },
5b0cb1d8
JK
11147 {
11148 .iface = NID_MAPPING,
11149 .name = "Master Playback Switch",
11150 .private_value = 0x1b,
11151 },
834be88d
TI
11152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11154 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11157 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11158 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11159 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11160 { } /* end */
11161};
11162
0e31daf7
J
11163/* bind hp and internal speaker mute (with plug check) */
11164static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11165 struct snd_ctl_elem_value *ucontrol)
11166{
11167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11168 long *valp = ucontrol->value.integer.value;
11169 int change;
11170
8de56b7d 11171 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11172 if (change)
11173 alc262_lenovo_3000_automute(codec, 0);
11174 return change;
11175}
11176
11177static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11178 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11179 {
11180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11181 .name = "Master Playback Switch",
5e26dfd0 11182 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11183 .info = snd_hda_mixer_amp_switch_info,
11184 .get = snd_hda_mixer_amp_switch_get,
11185 .put = alc262_lenovo_3000_master_sw_put,
11186 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11187 },
11188 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11189 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11193 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11194 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11195 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11196 { } /* end */
11197};
11198
9f99a638
HM
11199static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11200 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11201 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11204 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11205 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11206 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11207 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11208 { } /* end */
11209};
11210
304dcaac
TI
11211/* additional init verbs for Benq laptops */
11212static struct hda_verb alc262_EAPD_verbs[] = {
11213 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11214 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11215 {}
11216};
11217
83c34218
KY
11218static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11219 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11220 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11221
11222 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11223 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11224 {}
11225};
11226
f651b50b
TD
11227/* Samsung Q1 Ultra Vista model setup */
11228static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11229 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11230 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11231 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11232 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11233 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11234 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11235 { } /* end */
11236};
11237
11238static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11239 /* output mixer */
11240 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11243 /* speaker */
11244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11245 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11246 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11247 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11248 /* HP */
f651b50b 11249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11251 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11252 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11253 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11254 /* internal mic */
11255 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11256 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11257 /* ADC, choose mic */
11258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11259 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11260 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11261 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11262 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11264 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11266 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11267 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11268 {}
11269};
11270
f651b50b
TD
11271/* mute/unmute internal speaker according to the hp jack and mute state */
11272static void alc262_ultra_automute(struct hda_codec *codec)
11273{
11274 struct alc_spec *spec = codec->spec;
11275 unsigned int mute;
f651b50b 11276
bb9f76cd
TI
11277 mute = 0;
11278 /* auto-mute only when HP is used as HP */
11279 if (!spec->cur_mux[0]) {
864f92be 11280 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11281 if (spec->jack_present)
11282 mute = HDA_AMP_MUTE;
f651b50b 11283 }
bb9f76cd
TI
11284 /* mute/unmute internal speaker */
11285 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11286 HDA_AMP_MUTE, mute);
11287 /* mute/unmute HP */
11288 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11289 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11290}
11291
11292/* unsolicited event for HP jack sensing */
11293static void alc262_ultra_unsol_event(struct hda_codec *codec,
11294 unsigned int res)
11295{
11296 if ((res >> 26) != ALC880_HP_EVENT)
11297 return;
11298 alc262_ultra_automute(codec);
11299}
11300
bb9f76cd
TI
11301static struct hda_input_mux alc262_ultra_capture_source = {
11302 .num_items = 2,
11303 .items = {
11304 { "Mic", 0x1 },
11305 { "Headphone", 0x7 },
11306 },
11307};
11308
11309static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11310 struct snd_ctl_elem_value *ucontrol)
11311{
11312 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11313 struct alc_spec *spec = codec->spec;
11314 int ret;
11315
54cbc9ab 11316 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11317 if (!ret)
11318 return 0;
11319 /* reprogram the HP pin as mic or HP according to the input source */
11320 snd_hda_codec_write_cache(codec, 0x15, 0,
11321 AC_VERB_SET_PIN_WIDGET_CONTROL,
11322 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11323 alc262_ultra_automute(codec); /* mute/unmute HP */
11324 return ret;
11325}
11326
11327static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11328 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11329 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11330 {
11331 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11332 .name = "Capture Source",
54cbc9ab
TI
11333 .info = alc_mux_enum_info,
11334 .get = alc_mux_enum_get,
bb9f76cd
TI
11335 .put = alc262_ultra_mux_enum_put,
11336 },
5b0cb1d8
JK
11337 {
11338 .iface = NID_MAPPING,
11339 .name = "Capture Source",
11340 .private_value = 0x15,
11341 },
bb9f76cd
TI
11342 { } /* end */
11343};
11344
c3fc1f50
TI
11345/* We use two mixers depending on the output pin; 0x16 is a mono output
11346 * and thus it's bound with a different mixer.
11347 * This function returns which mixer amp should be used.
11348 */
11349static int alc262_check_volbit(hda_nid_t nid)
11350{
11351 if (!nid)
11352 return 0;
11353 else if (nid == 0x16)
11354 return 2;
11355 else
11356 return 1;
11357}
11358
11359static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11360 const char *pfx, int *vbits)
11361{
c3fc1f50
TI
11362 unsigned long val;
11363 int vbit;
11364
11365 vbit = alc262_check_volbit(nid);
11366 if (!vbit)
11367 return 0;
11368 if (*vbits & vbit) /* a volume control for this mixer already there */
11369 return 0;
11370 *vbits |= vbit;
c3fc1f50
TI
11371 if (vbit == 2)
11372 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11373 else
11374 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11375 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11376}
11377
11378static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11379 const char *pfx)
11380{
c3fc1f50
TI
11381 unsigned long val;
11382
11383 if (!nid)
11384 return 0;
c3fc1f50
TI
11385 if (nid == 0x16)
11386 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11387 else
11388 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11389 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11390}
11391
df694daa 11392/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11393static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11394 const struct auto_pin_cfg *cfg)
df694daa 11395{
c3fc1f50
TI
11396 const char *pfx;
11397 int vbits;
df694daa
KY
11398 int err;
11399
11400 spec->multiout.num_dacs = 1; /* only use one dac */
11401 spec->multiout.dac_nids = spec->private_dac_nids;
11402 spec->multiout.dac_nids[0] = 2;
11403
c3fc1f50
TI
11404 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11405 pfx = "Master";
11406 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11407 pfx = "Speaker";
11408 else
11409 pfx = "Front";
11410 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11411 if (err < 0)
11412 return err;
11413 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11414 if (err < 0)
11415 return err;
11416 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11417 if (err < 0)
11418 return err;
df694daa 11419
c3fc1f50
TI
11420 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11421 alc262_check_volbit(cfg->speaker_pins[0]) |
11422 alc262_check_volbit(cfg->hp_pins[0]);
11423 if (vbits == 1 || vbits == 2)
11424 pfx = "Master"; /* only one mixer is used */
11425 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11426 pfx = "Speaker";
11427 else
11428 pfx = "Front";
11429 vbits = 0;
11430 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11431 if (err < 0)
11432 return err;
11433 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11434 &vbits);
11435 if (err < 0)
11436 return err;
11437 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11438 &vbits);
11439 if (err < 0)
11440 return err;
f12ab1e0 11441 return 0;
df694daa
KY
11442}
11443
05f5f477 11444#define alc262_auto_create_input_ctls \
eaa9b3a7 11445 alc882_auto_create_input_ctls
df694daa
KY
11446
11447/*
11448 * generic initialization of ADC, input mixers and output mixers
11449 */
11450static struct hda_verb alc262_volume_init_verbs[] = {
11451 /*
11452 * Unmute ADC0-2 and set the default input to mic-in
11453 */
11454 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11456 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11457 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11458 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11460
cb53c626 11461 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11462 * mixer widget
f12ab1e0
TI
11463 * Note: PASD motherboards uses the Line In 2 as the input for
11464 * front panel mic (mic 2)
df694daa
KY
11465 */
11466 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11467 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11468 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11469 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11470 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11471 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11472
11473 /*
11474 * Set up output mixers (0x0c - 0x0f)
11475 */
11476 /* set vol=0 to output mixers */
11477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11479 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11480
df694daa
KY
11481 /* set up input amps for analog loopback */
11482 /* Amp Indices: DAC = 0, mixer = 1 */
11483 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11484 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11485 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11486 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11487 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11488 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11489
11490 /* FIXME: use matrix-type input source selection */
11491 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11492 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11497 /* Input mixer2 */
11498 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11499 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11500 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11501 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11502 /* Input mixer3 */
11503 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11506 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11507
11508 { }
11509};
11510
9c7f852e
TI
11511static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11512 /*
11513 * Unmute ADC0-2 and set the default input to mic-in
11514 */
11515 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11517 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11519 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11521
cb53c626 11522 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11523 * mixer widget
f12ab1e0
TI
11524 * Note: PASD motherboards uses the Line In 2 as the input for
11525 * front panel mic (mic 2)
9c7f852e
TI
11526 */
11527 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11533 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11535
9c7f852e
TI
11536 /*
11537 * Set up output mixers (0x0c - 0x0e)
11538 */
11539 /* set vol=0 to output mixers */
11540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11541 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11542 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11543
11544 /* set up input amps for analog loopback */
11545 /* Amp Indices: DAC = 0, mixer = 1 */
11546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11552
ce875f07 11553 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11556
11557 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11559
11560 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11561 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11562
11563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11565 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11566 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11567 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11568
0e4835c1 11569 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11571 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11573 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11574 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11575
11576
11577 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
11578 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11579 /* Input mixer1: only unmute Mic */
9c7f852e 11580 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11581 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11582 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11583 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11584 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11585 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11586 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11587 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11588 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11589 /* Input mixer2 */
11590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11598 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11599 /* Input mixer3 */
11600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11603 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11604 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11605 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 11609
ce875f07
TI
11610 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11611
9c7f852e
TI
11612 { }
11613};
11614
cd7509a4
KY
11615static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11616 /*
11617 * Unmute ADC0-2 and set the default input to mic-in
11618 */
11619 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11621 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11622 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11623 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11624 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11625
cb53c626 11626 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
11627 * mixer widget
11628 * Note: PASD motherboards uses the Line In 2 as the input for front
11629 * panel mic (mic 2)
11630 */
11631 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11637 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11638 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
11640 /*
11641 * Set up output mixers (0x0c - 0x0e)
11642 */
11643 /* set vol=0 to output mixers */
11644 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11646 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11647
11648 /* set up input amps for analog loopback */
11649 /* Amp Indices: DAC = 0, mixer = 1 */
11650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11652 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11653 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11654 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11656
11657
11658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11659 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11660 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11661 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11662 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11663 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11664 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11665
11666 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11668
11669 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11670 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11671
11672 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11673 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11674 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11676 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11677 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11678
11679 /* FIXME: use matrix-type input source selection */
11680 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11681 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11682 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11683 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11684 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11685 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11687 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11689 /* Input mixer2 */
11690 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11691 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11694 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11695 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11696 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11697 /* Input mixer3 */
11698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11701 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11702 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11703 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11704 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11705
ce875f07
TI
11706 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11707
cd7509a4
KY
11708 { }
11709};
11710
9f99a638
HM
11711static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11712
11713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11715 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11716
11717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11719 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11721
11722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11723 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11724 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11725 {}
11726};
11727
11728
cb53c626
TI
11729#ifdef CONFIG_SND_HDA_POWER_SAVE
11730#define alc262_loopbacks alc880_loopbacks
11731#endif
11732
def319f9 11733/* pcm configuration: identical with ALC880 */
df694daa
KY
11734#define alc262_pcm_analog_playback alc880_pcm_analog_playback
11735#define alc262_pcm_analog_capture alc880_pcm_analog_capture
11736#define alc262_pcm_digital_playback alc880_pcm_digital_playback
11737#define alc262_pcm_digital_capture alc880_pcm_digital_capture
11738
11739/*
11740 * BIOS auto configuration
11741 */
11742static int alc262_parse_auto_config(struct hda_codec *codec)
11743{
11744 struct alc_spec *spec = codec->spec;
11745 int err;
11746 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11747
f12ab1e0
TI
11748 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11749 alc262_ignore);
11750 if (err < 0)
df694daa 11751 return err;
e64f14f4 11752 if (!spec->autocfg.line_outs) {
0852d7a6 11753 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
11754 spec->multiout.max_channels = 2;
11755 spec->no_analog = 1;
11756 goto dig_only;
11757 }
df694daa 11758 return 0; /* can't find valid BIOS pin config */
e64f14f4 11759 }
f12ab1e0
TI
11760 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11761 if (err < 0)
11762 return err;
05f5f477 11763 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 11764 if (err < 0)
df694daa
KY
11765 return err;
11766
11767 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11768
e64f14f4 11769 dig_only:
0852d7a6 11770 if (spec->autocfg.dig_outs) {
df694daa 11771 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 11772 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 11773 }
df694daa
KY
11774 if (spec->autocfg.dig_in_pin)
11775 spec->dig_in_nid = ALC262_DIGIN_NID;
11776
603c4019 11777 if (spec->kctls.list)
d88897ea 11778 add_mixer(spec, spec->kctls.list);
df694daa 11779
d88897ea 11780 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 11781 spec->num_mux_defs = 1;
61b9b9b1 11782 spec->input_mux = &spec->private_imux[0];
df694daa 11783
776e184e
TI
11784 err = alc_auto_add_mic_boost(codec);
11785 if (err < 0)
11786 return err;
11787
6227cdce 11788 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 11789
df694daa
KY
11790 return 1;
11791}
11792
11793#define alc262_auto_init_multi_out alc882_auto_init_multi_out
11794#define alc262_auto_init_hp_out alc882_auto_init_hp_out
11795#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 11796#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
11797
11798
11799/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 11800static void alc262_auto_init(struct hda_codec *codec)
df694daa 11801{
f6c7e546 11802 struct alc_spec *spec = codec->spec;
df694daa
KY
11803 alc262_auto_init_multi_out(codec);
11804 alc262_auto_init_hp_out(codec);
11805 alc262_auto_init_analog_input(codec);
f511b01c 11806 alc262_auto_init_input_src(codec);
f6c7e546 11807 if (spec->unsol_event)
7fb0d78f 11808 alc_inithook(codec);
df694daa
KY
11809}
11810
11811/*
11812 * configuration and preset
11813 */
f5fcc13c
TI
11814static const char *alc262_models[ALC262_MODEL_LAST] = {
11815 [ALC262_BASIC] = "basic",
11816 [ALC262_HIPPO] = "hippo",
11817 [ALC262_HIPPO_1] = "hippo_1",
11818 [ALC262_FUJITSU] = "fujitsu",
11819 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 11820 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 11821 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 11822 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 11823 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
11824 [ALC262_BENQ_T31] = "benq-t31",
11825 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 11826 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 11827 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 11828 [ALC262_ULTRA] = "ultra",
0e31daf7 11829 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 11830 [ALC262_NEC] = "nec",
ba340e82 11831 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
11832 [ALC262_AUTO] = "auto",
11833};
11834
11835static struct snd_pci_quirk alc262_cfg_tbl[] = {
11836 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 11837 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
11838 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11839 ALC262_HP_BPC),
11840 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11841 ALC262_HP_BPC),
53eff7e1
TI
11842 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11843 ALC262_HP_BPC),
cd7509a4 11844 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11845 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11846 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11847 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11848 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11849 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 11850 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 11851 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
11852 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11853 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11854 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
11855 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11856 ALC262_HP_TC_T5735),
8c427226 11857 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 11858 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 11859 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 11860 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 11861 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 11862 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 11863 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 11864 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 11865#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
11866 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11867 ALC262_SONY_ASSAMD),
c5b5165c 11868#endif
36ca6e13 11869 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 11870 ALC262_TOSHIBA_RX1),
80ffe869 11871 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 11872 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 11873 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 11874 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
11875 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11876 ALC262_ULTRA),
3e420e78 11877 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 11878 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
11879 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11880 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11881 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
11882 {}
11883};
11884
11885static struct alc_config_preset alc262_presets[] = {
11886 [ALC262_BASIC] = {
11887 .mixers = { alc262_base_mixer },
11888 .init_verbs = { alc262_init_verbs },
11889 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11890 .dac_nids = alc262_dac_nids,
11891 .hp_nid = 0x03,
11892 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11893 .channel_mode = alc262_modes,
a3bcba38 11894 .input_mux = &alc262_capture_source,
df694daa 11895 },
ccc656ce 11896 [ALC262_HIPPO] = {
42171c17 11897 .mixers = { alc262_hippo_mixer },
6732bd0d 11898 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
11899 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11900 .dac_nids = alc262_dac_nids,
11901 .hp_nid = 0x03,
11902 .dig_out_nid = ALC262_DIGOUT_NID,
11903 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11904 .channel_mode = alc262_modes,
11905 .input_mux = &alc262_capture_source,
11906 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11907 .setup = alc262_hippo_setup,
11908 .init_hook = alc262_hippo_automute,
ccc656ce
KY
11909 },
11910 [ALC262_HIPPO_1] = {
11911 .mixers = { alc262_hippo1_mixer },
11912 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11913 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11914 .dac_nids = alc262_dac_nids,
11915 .hp_nid = 0x02,
11916 .dig_out_nid = ALC262_DIGOUT_NID,
11917 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11918 .channel_mode = alc262_modes,
11919 .input_mux = &alc262_capture_source,
42171c17 11920 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
11921 .setup = alc262_hippo1_setup,
11922 .init_hook = alc262_hippo_automute,
ccc656ce 11923 },
834be88d
TI
11924 [ALC262_FUJITSU] = {
11925 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
11926 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11927 alc262_fujitsu_unsol_verbs },
834be88d
TI
11928 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11929 .dac_nids = alc262_dac_nids,
11930 .hp_nid = 0x03,
11931 .dig_out_nid = ALC262_DIGOUT_NID,
11932 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11933 .channel_mode = alc262_modes,
11934 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 11935 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 11936 .init_hook = alc262_fujitsu_init_hook,
834be88d 11937 },
9c7f852e
TI
11938 [ALC262_HP_BPC] = {
11939 .mixers = { alc262_HP_BPC_mixer },
11940 .init_verbs = { alc262_HP_BPC_init_verbs },
11941 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11942 .dac_nids = alc262_dac_nids,
11943 .hp_nid = 0x03,
11944 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11945 .channel_mode = alc262_modes,
11946 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
11947 .unsol_event = alc262_hp_bpc_unsol_event,
11948 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 11949 },
cd7509a4
KY
11950 [ALC262_HP_BPC_D7000_WF] = {
11951 .mixers = { alc262_HP_BPC_WildWest_mixer },
11952 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11953 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11954 .dac_nids = alc262_dac_nids,
11955 .hp_nid = 0x03,
11956 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11957 .channel_mode = alc262_modes,
accbe498 11958 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11959 .unsol_event = alc262_hp_wildwest_unsol_event,
11960 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11961 },
cd7509a4
KY
11962 [ALC262_HP_BPC_D7000_WL] = {
11963 .mixers = { alc262_HP_BPC_WildWest_mixer,
11964 alc262_HP_BPC_WildWest_option_mixer },
11965 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11966 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11967 .dac_nids = alc262_dac_nids,
11968 .hp_nid = 0x03,
11969 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11970 .channel_mode = alc262_modes,
accbe498 11971 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11972 .unsol_event = alc262_hp_wildwest_unsol_event,
11973 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11974 },
66d2a9d6
KY
11975 [ALC262_HP_TC_T5735] = {
11976 .mixers = { alc262_hp_t5735_mixer },
11977 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11978 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11979 .dac_nids = alc262_dac_nids,
11980 .hp_nid = 0x03,
11981 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11982 .channel_mode = alc262_modes,
11983 .input_mux = &alc262_capture_source,
dc99be47 11984 .unsol_event = alc_sku_unsol_event,
4f5d1706 11985 .setup = alc262_hp_t5735_setup,
dc99be47 11986 .init_hook = alc_inithook,
8c427226
KY
11987 },
11988 [ALC262_HP_RP5700] = {
11989 .mixers = { alc262_hp_rp5700_mixer },
11990 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11991 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11992 .dac_nids = alc262_dac_nids,
11993 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11994 .channel_mode = alc262_modes,
11995 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 11996 },
304dcaac
TI
11997 [ALC262_BENQ_ED8] = {
11998 .mixers = { alc262_base_mixer },
11999 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12000 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12001 .dac_nids = alc262_dac_nids,
12002 .hp_nid = 0x03,
12003 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12004 .channel_mode = alc262_modes,
12005 .input_mux = &alc262_capture_source,
f12ab1e0 12006 },
272a527c
KY
12007 [ALC262_SONY_ASSAMD] = {
12008 .mixers = { alc262_sony_mixer },
12009 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12010 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12011 .dac_nids = alc262_dac_nids,
12012 .hp_nid = 0x02,
12013 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12014 .channel_mode = alc262_modes,
12015 .input_mux = &alc262_capture_source,
12016 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12017 .setup = alc262_hippo_setup,
12018 .init_hook = alc262_hippo_automute,
83c34218
KY
12019 },
12020 [ALC262_BENQ_T31] = {
12021 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12022 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12023 alc_hp15_unsol_verbs },
83c34218
KY
12024 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12025 .dac_nids = alc262_dac_nids,
12026 .hp_nid = 0x03,
12027 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12028 .channel_mode = alc262_modes,
12029 .input_mux = &alc262_capture_source,
12030 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12031 .setup = alc262_hippo_setup,
12032 .init_hook = alc262_hippo_automute,
ea1fb29a 12033 },
f651b50b 12034 [ALC262_ULTRA] = {
f9e336f6
TI
12035 .mixers = { alc262_ultra_mixer },
12036 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12037 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12038 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12039 .dac_nids = alc262_dac_nids,
f651b50b
TD
12040 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12041 .channel_mode = alc262_modes,
12042 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12043 .adc_nids = alc262_adc_nids, /* ADC0 */
12044 .capsrc_nids = alc262_capsrc_nids,
12045 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12046 .unsol_event = alc262_ultra_unsol_event,
12047 .init_hook = alc262_ultra_automute,
12048 },
0e31daf7
J
12049 [ALC262_LENOVO_3000] = {
12050 .mixers = { alc262_lenovo_3000_mixer },
12051 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12052 alc262_lenovo_3000_unsol_verbs,
12053 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12054 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12055 .dac_nids = alc262_dac_nids,
12056 .hp_nid = 0x03,
12057 .dig_out_nid = ALC262_DIGOUT_NID,
12058 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12059 .channel_mode = alc262_modes,
12060 .input_mux = &alc262_fujitsu_capture_source,
12061 .unsol_event = alc262_lenovo_3000_unsol_event,
12062 },
e8f9ae2a
PT
12063 [ALC262_NEC] = {
12064 .mixers = { alc262_nec_mixer },
12065 .init_verbs = { alc262_nec_verbs },
12066 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12067 .dac_nids = alc262_dac_nids,
12068 .hp_nid = 0x03,
12069 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12070 .channel_mode = alc262_modes,
12071 .input_mux = &alc262_capture_source,
12072 },
4e555fe5
KY
12073 [ALC262_TOSHIBA_S06] = {
12074 .mixers = { alc262_toshiba_s06_mixer },
12075 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12076 alc262_eapd_verbs },
12077 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12078 .capsrc_nids = alc262_dmic_capsrc_nids,
12079 .dac_nids = alc262_dac_nids,
12080 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12081 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12082 .dig_out_nid = ALC262_DIGOUT_NID,
12083 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12084 .channel_mode = alc262_modes,
4f5d1706
TI
12085 .unsol_event = alc_sku_unsol_event,
12086 .setup = alc262_toshiba_s06_setup,
12087 .init_hook = alc_inithook,
4e555fe5 12088 },
9f99a638
HM
12089 [ALC262_TOSHIBA_RX1] = {
12090 .mixers = { alc262_toshiba_rx1_mixer },
12091 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12092 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12093 .dac_nids = alc262_dac_nids,
12094 .hp_nid = 0x03,
12095 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12096 .channel_mode = alc262_modes,
12097 .input_mux = &alc262_capture_source,
12098 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12099 .setup = alc262_hippo_setup,
12100 .init_hook = alc262_hippo_automute,
9f99a638 12101 },
ba340e82
TV
12102 [ALC262_TYAN] = {
12103 .mixers = { alc262_tyan_mixer },
12104 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12105 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12106 .dac_nids = alc262_dac_nids,
12107 .hp_nid = 0x02,
12108 .dig_out_nid = ALC262_DIGOUT_NID,
12109 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12110 .channel_mode = alc262_modes,
12111 .input_mux = &alc262_capture_source,
a9fd4f3f 12112 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12113 .setup = alc262_tyan_setup,
12114 .init_hook = alc_automute_amp,
ba340e82 12115 },
df694daa
KY
12116};
12117
12118static int patch_alc262(struct hda_codec *codec)
12119{
12120 struct alc_spec *spec;
12121 int board_config;
12122 int err;
12123
dc041e0b 12124 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12125 if (spec == NULL)
12126 return -ENOMEM;
12127
12128 codec->spec = spec;
12129#if 0
f12ab1e0
TI
12130 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12131 * under-run
12132 */
df694daa
KY
12133 {
12134 int tmp;
12135 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12136 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12137 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12138 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12139 }
12140#endif
12141
2c3bf9ab
TI
12142 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12143
f5fcc13c
TI
12144 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12145 alc262_models,
12146 alc262_cfg_tbl);
cd7509a4 12147
f5fcc13c 12148 if (board_config < 0) {
9a11f1aa
TI
12149 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12150 codec->chip_name);
df694daa
KY
12151 board_config = ALC262_AUTO;
12152 }
12153
12154 if (board_config == ALC262_AUTO) {
12155 /* automatic parse from the BIOS config */
12156 err = alc262_parse_auto_config(codec);
12157 if (err < 0) {
12158 alc_free(codec);
12159 return err;
f12ab1e0 12160 } else if (!err) {
9c7f852e
TI
12161 printk(KERN_INFO
12162 "hda_codec: Cannot set up configuration "
12163 "from BIOS. Using base mode...\n");
df694daa
KY
12164 board_config = ALC262_BASIC;
12165 }
12166 }
12167
07eba61d
TI
12168 if (!spec->no_analog) {
12169 err = snd_hda_attach_beep_device(codec, 0x1);
12170 if (err < 0) {
12171 alc_free(codec);
12172 return err;
12173 }
680cd536
KK
12174 }
12175
df694daa 12176 if (board_config != ALC262_AUTO)
e9c364c0 12177 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12178
df694daa
KY
12179 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12180 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12181
df694daa
KY
12182 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12183 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12184
f12ab1e0 12185 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12186 int i;
12187 /* check whether the digital-mic has to be supported */
12188 for (i = 0; i < spec->input_mux->num_items; i++) {
12189 if (spec->input_mux->items[i].index >= 9)
12190 break;
12191 }
12192 if (i < spec->input_mux->num_items) {
12193 /* use only ADC0 */
12194 spec->adc_nids = alc262_dmic_adc_nids;
12195 spec->num_adc_nids = 1;
12196 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12197 } else {
8c927b4a
TI
12198 /* all analog inputs */
12199 /* check whether NID 0x07 is valid */
12200 unsigned int wcap = get_wcaps(codec, 0x07);
12201
12202 /* get type */
a22d543a 12203 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12204 if (wcap != AC_WID_AUD_IN) {
12205 spec->adc_nids = alc262_adc_nids_alt;
12206 spec->num_adc_nids =
12207 ARRAY_SIZE(alc262_adc_nids_alt);
12208 spec->capsrc_nids = alc262_capsrc_nids_alt;
12209 } else {
12210 spec->adc_nids = alc262_adc_nids;
12211 spec->num_adc_nids =
12212 ARRAY_SIZE(alc262_adc_nids);
12213 spec->capsrc_nids = alc262_capsrc_nids;
12214 }
df694daa
KY
12215 }
12216 }
e64f14f4 12217 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12218 set_capture_mixer(codec);
07eba61d
TI
12219 if (!spec->no_analog)
12220 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12221
2134ea4f
TI
12222 spec->vmaster_nid = 0x0c;
12223
df694daa
KY
12224 codec->patch_ops = alc_patch_ops;
12225 if (board_config == ALC262_AUTO)
ae6b813a 12226 spec->init_hook = alc262_auto_init;
cb53c626
TI
12227#ifdef CONFIG_SND_HDA_POWER_SAVE
12228 if (!spec->loopback.amplist)
12229 spec->loopback.amplist = alc262_loopbacks;
12230#endif
ea1fb29a 12231
df694daa
KY
12232 return 0;
12233}
12234
a361d84b
KY
12235/*
12236 * ALC268 channel source setting (2 channel)
12237 */
12238#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12239#define alc268_modes alc260_modes
ea1fb29a 12240
a361d84b
KY
12241static hda_nid_t alc268_dac_nids[2] = {
12242 /* front, hp */
12243 0x02, 0x03
12244};
12245
12246static hda_nid_t alc268_adc_nids[2] = {
12247 /* ADC0-1 */
12248 0x08, 0x07
12249};
12250
12251static hda_nid_t alc268_adc_nids_alt[1] = {
12252 /* ADC0 */
12253 0x08
12254};
12255
e1406348
TI
12256static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12257
a361d84b
KY
12258static struct snd_kcontrol_new alc268_base_mixer[] = {
12259 /* output mixer control */
12260 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12261 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12262 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12264 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12265 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12266 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12267 { }
12268};
12269
42171c17
TI
12270static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12271 /* output mixer control */
12272 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12273 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12274 ALC262_HIPPO_MASTER_SWITCH,
12275 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12276 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12277 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12278 { }
12279};
12280
aef9d318
TI
12281/* bind Beep switches of both NID 0x0f and 0x10 */
12282static struct hda_bind_ctls alc268_bind_beep_sw = {
12283 .ops = &snd_hda_bind_sw,
12284 .values = {
12285 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12286 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12287 0
12288 },
12289};
12290
12291static struct snd_kcontrol_new alc268_beep_mixer[] = {
12292 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12293 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12294 { }
12295};
12296
d1a991a6
KY
12297static struct hda_verb alc268_eapd_verbs[] = {
12298 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12299 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12300 { }
12301};
12302
d273809e 12303/* Toshiba specific */
d273809e
TI
12304static struct hda_verb alc268_toshiba_verbs[] = {
12305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12306 { } /* end */
12307};
12308
12309/* Acer specific */
889c4395 12310/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12311static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12312 .ops = &snd_hda_bind_vol,
12313 .values = {
12314 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12315 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12316 0
12317 },
12318};
12319
889c4395
TI
12320/* mute/unmute internal speaker according to the hp jack and mute state */
12321static void alc268_acer_automute(struct hda_codec *codec, int force)
12322{
12323 struct alc_spec *spec = codec->spec;
12324 unsigned int mute;
12325
12326 if (force || !spec->sense_updated) {
864f92be 12327 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12328 spec->sense_updated = 1;
12329 }
12330 if (spec->jack_present)
12331 mute = HDA_AMP_MUTE; /* mute internal speaker */
12332 else /* unmute internal speaker if necessary */
12333 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12334 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12335 HDA_AMP_MUTE, mute);
12336}
12337
12338
12339/* bind hp and internal speaker mute (with plug check) */
12340static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12341 struct snd_ctl_elem_value *ucontrol)
12342{
12343 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12344 long *valp = ucontrol->value.integer.value;
12345 int change;
12346
8de56b7d 12347 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12348 if (change)
12349 alc268_acer_automute(codec, 0);
12350 return change;
12351}
d273809e 12352
8ef355da
KY
12353static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12354 /* output mixer control */
12355 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12356 {
12357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12358 .name = "Master Playback Switch",
5e26dfd0 12359 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12360 .info = snd_hda_mixer_amp_switch_info,
12361 .get = snd_hda_mixer_amp_switch_get,
12362 .put = alc268_acer_master_sw_put,
12363 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12364 },
12365 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12366 { }
12367};
12368
d273809e
TI
12369static struct snd_kcontrol_new alc268_acer_mixer[] = {
12370 /* output mixer control */
12371 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12372 {
12373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12374 .name = "Master Playback Switch",
5e26dfd0 12375 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12376 .info = snd_hda_mixer_amp_switch_info,
12377 .get = snd_hda_mixer_amp_switch_get,
12378 .put = alc268_acer_master_sw_put,
12379 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12380 },
33bf17ab
TI
12381 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12382 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12383 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12384 { }
12385};
12386
c238b4f4
TI
12387static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12388 /* output mixer control */
12389 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12390 {
12391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12392 .name = "Master Playback Switch",
5e26dfd0 12393 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12394 .info = snd_hda_mixer_amp_switch_info,
12395 .get = snd_hda_mixer_amp_switch_get,
12396 .put = alc268_acer_master_sw_put,
12397 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12398 },
12399 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12400 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12401 { }
12402};
12403
8ef355da
KY
12404static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12405 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12407 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12408 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12409 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12410 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12411 { }
12412};
12413
d273809e 12414static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12415 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12416 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12417 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12418 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12419 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12420 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12421 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12422 { }
12423};
12424
12425/* unsolicited event for HP jack sensing */
42171c17 12426#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12427#define alc268_toshiba_setup alc262_hippo_setup
12428#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12429
12430static void alc268_acer_unsol_event(struct hda_codec *codec,
12431 unsigned int res)
12432{
889c4395 12433 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12434 return;
12435 alc268_acer_automute(codec, 1);
12436}
12437
889c4395
TI
12438static void alc268_acer_init_hook(struct hda_codec *codec)
12439{
12440 alc268_acer_automute(codec, 1);
12441}
12442
8ef355da
KY
12443/* toggle speaker-output according to the hp-jack state */
12444static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12445{
12446 unsigned int present;
12447 unsigned char bits;
12448
864f92be 12449 present = snd_hda_jack_detect(codec, 0x15);
8ef355da
KY
12450 bits = present ? AMP_IN_MUTE(0) : 0;
12451 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12452 AMP_IN_MUTE(0), bits);
12453 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12454 AMP_IN_MUTE(0), bits);
12455}
12456
8ef355da
KY
12457static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12458 unsigned int res)
12459{
4f5d1706
TI
12460 switch (res >> 26) {
12461 case ALC880_HP_EVENT:
8ef355da 12462 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12463 break;
12464 case ALC880_MIC_EVENT:
12465 alc_mic_automute(codec);
12466 break;
12467 }
12468}
12469
12470static void alc268_acer_lc_setup(struct hda_codec *codec)
12471{
12472 struct alc_spec *spec = codec->spec;
12473 spec->ext_mic.pin = 0x18;
12474 spec->ext_mic.mux_idx = 0;
12475 spec->int_mic.pin = 0x12;
12476 spec->int_mic.mux_idx = 6;
12477 spec->auto_mic = 1;
8ef355da
KY
12478}
12479
12480static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12481{
12482 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12483 alc_mic_automute(codec);
8ef355da
KY
12484}
12485
3866f0b0
TI
12486static struct snd_kcontrol_new alc268_dell_mixer[] = {
12487 /* output mixer control */
12488 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12489 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12490 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12492 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12493 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12494 { }
12495};
12496
12497static struct hda_verb alc268_dell_verbs[] = {
12498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12500 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12501 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12502 { }
12503};
12504
12505/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12506static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12507{
a9fd4f3f 12508 struct alc_spec *spec = codec->spec;
3866f0b0 12509
a9fd4f3f
TI
12510 spec->autocfg.hp_pins[0] = 0x15;
12511 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12512 spec->ext_mic.pin = 0x18;
12513 spec->ext_mic.mux_idx = 0;
12514 spec->int_mic.pin = 0x19;
12515 spec->int_mic.mux_idx = 1;
12516 spec->auto_mic = 1;
3866f0b0
TI
12517}
12518
eb5a6621
HRK
12519static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12520 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12521 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12523 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12524 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12525 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12526 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12527 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12528 { }
12529};
12530
12531static struct hda_verb alc267_quanta_il1_verbs[] = {
12532 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12533 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12534 { }
12535};
12536
4f5d1706 12537static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12538{
a9fd4f3f 12539 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12540 spec->autocfg.hp_pins[0] = 0x15;
12541 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12542 spec->ext_mic.pin = 0x18;
12543 spec->ext_mic.mux_idx = 0;
12544 spec->int_mic.pin = 0x19;
12545 spec->int_mic.mux_idx = 1;
12546 spec->auto_mic = 1;
eb5a6621
HRK
12547}
12548
a361d84b
KY
12549/*
12550 * generic initialization of ADC, input mixers and output mixers
12551 */
12552static struct hda_verb alc268_base_init_verbs[] = {
12553 /* Unmute DAC0-1 and set vol = 0 */
12554 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12555 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12556
12557 /*
12558 * Set up output mixers (0x0c - 0x0e)
12559 */
12560 /* set vol=0 to output mixers */
12561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12562 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12563
12564 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12565 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12566
12567 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12569 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12570 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12572 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12573 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12574 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12575
12576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12580 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12581
12582 /* set PCBEEP vol = 0, mute connections */
12583 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12584 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12585 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12586
a9b3aa8a 12587 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12588
a9b3aa8a
JZ
12589 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12591 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 12593
a361d84b
KY
12594 { }
12595};
12596
12597/*
12598 * generic initialization of ADC, input mixers and output mixers
12599 */
12600static struct hda_verb alc268_volume_init_verbs[] = {
12601 /* set output DAC */
4cfb91c6
TI
12602 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12603 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12604
12605 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12606 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12607 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12608 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12609 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12610
a361d84b 12611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12612 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12613 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12614
12615 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12616 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12617
aef9d318
TI
12618 /* set PCBEEP vol = 0, mute connections */
12619 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12620 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12621 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
12622
12623 { }
12624};
12625
fdbc6626
TI
12626static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12627 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12628 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12629 { } /* end */
12630};
12631
a361d84b
KY
12632static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12633 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12634 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 12635 _DEFINE_CAPSRC(1),
a361d84b
KY
12636 { } /* end */
12637};
12638
12639static struct snd_kcontrol_new alc268_capture_mixer[] = {
12640 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12641 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12642 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12643 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 12644 _DEFINE_CAPSRC(2),
a361d84b
KY
12645 { } /* end */
12646};
12647
12648static struct hda_input_mux alc268_capture_source = {
12649 .num_items = 4,
12650 .items = {
12651 { "Mic", 0x0 },
12652 { "Front Mic", 0x1 },
12653 { "Line", 0x2 },
12654 { "CD", 0x3 },
12655 },
12656};
12657
0ccb541c 12658static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
12659 .num_items = 3,
12660 .items = {
12661 { "Mic", 0x0 },
12662 { "Internal Mic", 0x1 },
12663 { "Line", 0x2 },
12664 },
12665};
12666
12667static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
12668 .num_items = 3,
12669 .items = {
12670 { "Mic", 0x0 },
12671 { "Internal Mic", 0x6 },
12672 { "Line", 0x2 },
12673 },
12674};
12675
86c53bd2
JW
12676#ifdef CONFIG_SND_DEBUG
12677static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
12678 /* Volume widgets */
12679 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12680 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12681 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12682 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12683 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12684 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12685 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12686 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12687 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12688 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12689 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12690 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12691 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
12692 /* The below appears problematic on some hardwares */
12693 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
12694 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12695 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12696 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12697 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12698
12699 /* Modes for retasking pin widgets */
12700 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12701 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12702 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12703 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12704
12705 /* Controls for GPIO pins, assuming they are configured as outputs */
12706 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12707 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12708 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12709 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12710
12711 /* Switches to allow the digital SPDIF output pin to be enabled.
12712 * The ALC268 does not have an SPDIF input.
12713 */
12714 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12715
12716 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12717 * this output to turn on an external amplifier.
12718 */
12719 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12720 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12721
12722 { } /* end */
12723};
12724#endif
12725
a361d84b
KY
12726/* create input playback/capture controls for the given pin */
12727static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12728 const char *ctlname, int idx)
12729{
3f3b7c1a 12730 hda_nid_t dac;
a361d84b
KY
12731 int err;
12732
3f3b7c1a
TI
12733 switch (nid) {
12734 case 0x14:
12735 case 0x16:
12736 dac = 0x02;
12737 break;
12738 case 0x15:
12739 dac = 0x03;
12740 break;
12741 default:
12742 return 0;
12743 }
12744 if (spec->multiout.dac_nids[0] != dac &&
12745 spec->multiout.dac_nids[1] != dac) {
0afe5f89 12746 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 12747 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
12748 HDA_OUTPUT));
12749 if (err < 0)
12750 return err;
3f3b7c1a
TI
12751 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12752 }
12753
3f3b7c1a 12754 if (nid != 0x16)
0afe5f89 12755 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 12756 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 12757 else /* mono */
0afe5f89 12758 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 12759 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
12760 if (err < 0)
12761 return err;
12762 return 0;
12763}
12764
12765/* add playback controls from the parsed DAC table */
12766static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12767 const struct auto_pin_cfg *cfg)
12768{
12769 hda_nid_t nid;
12770 int err;
12771
a361d84b 12772 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
12773
12774 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
12775 if (nid) {
12776 const char *name;
12777 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12778 name = "Speaker";
12779 else
12780 name = "Front";
12781 err = alc268_new_analog_output(spec, nid, name, 0);
12782 if (err < 0)
12783 return err;
12784 }
a361d84b
KY
12785
12786 nid = cfg->speaker_pins[0];
12787 if (nid == 0x1d) {
0afe5f89 12788 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
12789 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12790 if (err < 0)
12791 return err;
3f3b7c1a
TI
12792 } else {
12793 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12794 if (err < 0)
12795 return err;
a361d84b
KY
12796 }
12797 nid = cfg->hp_pins[0];
3f3b7c1a
TI
12798 if (nid) {
12799 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12800 if (err < 0)
12801 return err;
12802 }
a361d84b
KY
12803
12804 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12805 if (nid == 0x16) {
0afe5f89 12806 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 12807 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
12808 if (err < 0)
12809 return err;
12810 }
ea1fb29a 12811 return 0;
a361d84b
KY
12812}
12813
12814/* create playback/capture controls for input pins */
05f5f477 12815static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
12816 const struct auto_pin_cfg *cfg)
12817{
05f5f477 12818 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
12819}
12820
e9af4f36
TI
12821static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12822 hda_nid_t nid, int pin_type)
12823{
12824 int idx;
12825
12826 alc_set_pin_output(codec, nid, pin_type);
12827 if (nid == 0x14 || nid == 0x16)
12828 idx = 0;
12829 else
12830 idx = 1;
12831 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12832}
12833
12834static void alc268_auto_init_multi_out(struct hda_codec *codec)
12835{
12836 struct alc_spec *spec = codec->spec;
12837 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12838 if (nid) {
12839 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12840 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12841 }
12842}
12843
12844static void alc268_auto_init_hp_out(struct hda_codec *codec)
12845{
12846 struct alc_spec *spec = codec->spec;
12847 hda_nid_t pin;
12848
12849 pin = spec->autocfg.hp_pins[0];
12850 if (pin)
12851 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12852 pin = spec->autocfg.speaker_pins[0];
12853 if (pin)
12854 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12855}
12856
a361d84b
KY
12857static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12858{
12859 struct alc_spec *spec = codec->spec;
12860 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12861 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12862 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12863 unsigned int dac_vol1, dac_vol2;
12864
e9af4f36 12865 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
12866 snd_hda_codec_write(codec, speaker_nid, 0,
12867 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 12868 /* mute mixer inputs from 0x1d */
a361d84b
KY
12869 snd_hda_codec_write(codec, 0x0f, 0,
12870 AC_VERB_SET_AMP_GAIN_MUTE,
12871 AMP_IN_UNMUTE(1));
12872 snd_hda_codec_write(codec, 0x10, 0,
12873 AC_VERB_SET_AMP_GAIN_MUTE,
12874 AMP_IN_UNMUTE(1));
12875 } else {
e9af4f36 12876 /* unmute mixer inputs from 0x1d */
a361d84b
KY
12877 snd_hda_codec_write(codec, 0x0f, 0,
12878 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12879 snd_hda_codec_write(codec, 0x10, 0,
12880 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12881 }
12882
12883 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 12884 if (line_nid == 0x14)
a361d84b
KY
12885 dac_vol2 = AMP_OUT_ZERO;
12886 else if (line_nid == 0x15)
12887 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 12888 if (hp_nid == 0x14)
a361d84b
KY
12889 dac_vol2 = AMP_OUT_ZERO;
12890 else if (hp_nid == 0x15)
12891 dac_vol1 = AMP_OUT_ZERO;
12892 if (line_nid != 0x16 || hp_nid != 0x16 ||
12893 spec->autocfg.line_out_pins[1] != 0x16 ||
12894 spec->autocfg.line_out_pins[2] != 0x16)
12895 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12896
12897 snd_hda_codec_write(codec, 0x02, 0,
12898 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12899 snd_hda_codec_write(codec, 0x03, 0,
12900 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12901}
12902
def319f9 12903/* pcm configuration: identical with ALC880 */
a361d84b
KY
12904#define alc268_pcm_analog_playback alc880_pcm_analog_playback
12905#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 12906#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
12907#define alc268_pcm_digital_playback alc880_pcm_digital_playback
12908
12909/*
12910 * BIOS auto configuration
12911 */
12912static int alc268_parse_auto_config(struct hda_codec *codec)
12913{
12914 struct alc_spec *spec = codec->spec;
12915 int err;
12916 static hda_nid_t alc268_ignore[] = { 0 };
12917
12918 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12919 alc268_ignore);
12920 if (err < 0)
12921 return err;
7e0e44d4
TI
12922 if (!spec->autocfg.line_outs) {
12923 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12924 spec->multiout.max_channels = 2;
12925 spec->no_analog = 1;
12926 goto dig_only;
12927 }
a361d84b 12928 return 0; /* can't find valid BIOS pin config */
7e0e44d4 12929 }
a361d84b
KY
12930 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12931 if (err < 0)
12932 return err;
05f5f477 12933 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
12934 if (err < 0)
12935 return err;
12936
12937 spec->multiout.max_channels = 2;
12938
7e0e44d4 12939 dig_only:
a361d84b 12940 /* digital only support output */
7e0e44d4 12941 if (spec->autocfg.dig_outs) {
a361d84b 12942 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
12943 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12944 }
603c4019 12945 if (spec->kctls.list)
d88897ea 12946 add_mixer(spec, spec->kctls.list);
a361d84b 12947
892981ff 12948 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 12949 add_mixer(spec, alc268_beep_mixer);
aef9d318 12950
d88897ea 12951 add_verb(spec, alc268_volume_init_verbs);
5908589f 12952 spec->num_mux_defs = 2;
61b9b9b1 12953 spec->input_mux = &spec->private_imux[0];
a361d84b 12954
776e184e
TI
12955 err = alc_auto_add_mic_boost(codec);
12956 if (err < 0)
12957 return err;
12958
6227cdce 12959 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 12960
a361d84b
KY
12961 return 1;
12962}
12963
a361d84b
KY
12964#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12965
12966/* init callback for auto-configuration model -- overriding the default init */
12967static void alc268_auto_init(struct hda_codec *codec)
12968{
f6c7e546 12969 struct alc_spec *spec = codec->spec;
a361d84b
KY
12970 alc268_auto_init_multi_out(codec);
12971 alc268_auto_init_hp_out(codec);
12972 alc268_auto_init_mono_speaker_out(codec);
12973 alc268_auto_init_analog_input(codec);
f6c7e546 12974 if (spec->unsol_event)
7fb0d78f 12975 alc_inithook(codec);
a361d84b
KY
12976}
12977
12978/*
12979 * configuration and preset
12980 */
12981static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 12982 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 12983 [ALC268_3ST] = "3stack",
983f8ae4 12984 [ALC268_TOSHIBA] = "toshiba",
d273809e 12985 [ALC268_ACER] = "acer",
c238b4f4 12986 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 12987 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 12988 [ALC268_DELL] = "dell",
f12462c5 12989 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
12990#ifdef CONFIG_SND_DEBUG
12991 [ALC268_TEST] = "test",
12992#endif
a361d84b
KY
12993 [ALC268_AUTO] = "auto",
12994};
12995
12996static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 12997 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 12998 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 12999 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13000 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13001 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13002 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13003 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13004 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13005 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13006 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13007 /* almost compatible with toshiba but with optional digital outs;
13008 * auto-probing seems working fine
13009 */
8871e5b9 13010 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13011 ALC268_AUTO),
a361d84b 13012 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13013 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13014 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13015 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13016 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13017 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13018 {}
13019};
13020
3abf2f36
TI
13021/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13022static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13023 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13024 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13025 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13026 ALC268_TOSHIBA),
13027 {}
13028};
13029
a361d84b 13030static struct alc_config_preset alc268_presets[] = {
eb5a6621 13031 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13032 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13033 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13034 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13035 alc267_quanta_il1_verbs },
13036 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13037 .dac_nids = alc268_dac_nids,
13038 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13039 .adc_nids = alc268_adc_nids_alt,
13040 .hp_nid = 0x03,
13041 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13042 .channel_mode = alc268_modes,
4f5d1706
TI
13043 .unsol_event = alc_sku_unsol_event,
13044 .setup = alc267_quanta_il1_setup,
13045 .init_hook = alc_inithook,
eb5a6621 13046 },
a361d84b 13047 [ALC268_3ST] = {
aef9d318
TI
13048 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13049 alc268_beep_mixer },
a361d84b
KY
13050 .init_verbs = { alc268_base_init_verbs },
13051 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13052 .dac_nids = alc268_dac_nids,
13053 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13054 .adc_nids = alc268_adc_nids_alt,
e1406348 13055 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13056 .hp_nid = 0x03,
13057 .dig_out_nid = ALC268_DIGOUT_NID,
13058 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13059 .channel_mode = alc268_modes,
13060 .input_mux = &alc268_capture_source,
13061 },
d1a991a6 13062 [ALC268_TOSHIBA] = {
42171c17 13063 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13064 alc268_beep_mixer },
d273809e
TI
13065 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13066 alc268_toshiba_verbs },
d1a991a6
KY
13067 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13068 .dac_nids = alc268_dac_nids,
13069 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13070 .adc_nids = alc268_adc_nids_alt,
e1406348 13071 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13072 .hp_nid = 0x03,
13073 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13074 .channel_mode = alc268_modes,
13075 .input_mux = &alc268_capture_source,
d273809e 13076 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13077 .setup = alc268_toshiba_setup,
13078 .init_hook = alc268_toshiba_automute,
d273809e
TI
13079 },
13080 [ALC268_ACER] = {
432fd133 13081 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13082 alc268_beep_mixer },
d273809e
TI
13083 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13084 alc268_acer_verbs },
13085 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13086 .dac_nids = alc268_dac_nids,
13087 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13088 .adc_nids = alc268_adc_nids_alt,
e1406348 13089 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13090 .hp_nid = 0x02,
13091 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13092 .channel_mode = alc268_modes,
0ccb541c 13093 .input_mux = &alc268_acer_capture_source,
d273809e 13094 .unsol_event = alc268_acer_unsol_event,
889c4395 13095 .init_hook = alc268_acer_init_hook,
d1a991a6 13096 },
c238b4f4
TI
13097 [ALC268_ACER_DMIC] = {
13098 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13099 alc268_beep_mixer },
13100 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13101 alc268_acer_verbs },
13102 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13103 .dac_nids = alc268_dac_nids,
13104 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13105 .adc_nids = alc268_adc_nids_alt,
13106 .capsrc_nids = alc268_capsrc_nids,
13107 .hp_nid = 0x02,
13108 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13109 .channel_mode = alc268_modes,
13110 .input_mux = &alc268_acer_dmic_capture_source,
13111 .unsol_event = alc268_acer_unsol_event,
13112 .init_hook = alc268_acer_init_hook,
13113 },
8ef355da
KY
13114 [ALC268_ACER_ASPIRE_ONE] = {
13115 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13116 alc268_beep_mixer,
fdbc6626 13117 alc268_capture_nosrc_mixer },
8ef355da
KY
13118 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13119 alc268_acer_aspire_one_verbs },
13120 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13121 .dac_nids = alc268_dac_nids,
13122 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13123 .adc_nids = alc268_adc_nids_alt,
13124 .capsrc_nids = alc268_capsrc_nids,
13125 .hp_nid = 0x03,
13126 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13127 .channel_mode = alc268_modes,
8ef355da 13128 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13129 .setup = alc268_acer_lc_setup,
8ef355da
KY
13130 .init_hook = alc268_acer_lc_init_hook,
13131 },
3866f0b0 13132 [ALC268_DELL] = {
fdbc6626
TI
13133 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13134 alc268_capture_nosrc_mixer },
3866f0b0
TI
13135 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13136 alc268_dell_verbs },
13137 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13138 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13139 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13140 .adc_nids = alc268_adc_nids_alt,
13141 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13142 .hp_nid = 0x02,
13143 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13144 .channel_mode = alc268_modes,
a9fd4f3f 13145 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13146 .setup = alc268_dell_setup,
13147 .init_hook = alc_inithook,
3866f0b0 13148 },
f12462c5 13149 [ALC268_ZEPTO] = {
aef9d318
TI
13150 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13151 alc268_beep_mixer },
f12462c5
MT
13152 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13153 alc268_toshiba_verbs },
13154 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13155 .dac_nids = alc268_dac_nids,
13156 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13157 .adc_nids = alc268_adc_nids_alt,
e1406348 13158 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13159 .hp_nid = 0x03,
13160 .dig_out_nid = ALC268_DIGOUT_NID,
13161 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13162 .channel_mode = alc268_modes,
13163 .input_mux = &alc268_capture_source,
4f5d1706
TI
13164 .setup = alc268_toshiba_setup,
13165 .init_hook = alc268_toshiba_automute,
f12462c5 13166 },
86c53bd2
JW
13167#ifdef CONFIG_SND_DEBUG
13168 [ALC268_TEST] = {
13169 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13170 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13171 alc268_volume_init_verbs },
13172 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13173 .dac_nids = alc268_dac_nids,
13174 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13175 .adc_nids = alc268_adc_nids_alt,
e1406348 13176 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13177 .hp_nid = 0x03,
13178 .dig_out_nid = ALC268_DIGOUT_NID,
13179 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13180 .channel_mode = alc268_modes,
13181 .input_mux = &alc268_capture_source,
13182 },
13183#endif
a361d84b
KY
13184};
13185
13186static int patch_alc268(struct hda_codec *codec)
13187{
13188 struct alc_spec *spec;
13189 int board_config;
22971e3a 13190 int i, has_beep, err;
a361d84b 13191
ef86f581 13192 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13193 if (spec == NULL)
13194 return -ENOMEM;
13195
13196 codec->spec = spec;
13197
13198 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13199 alc268_models,
13200 alc268_cfg_tbl);
13201
3abf2f36
TI
13202 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13203 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13204 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13205
a361d84b 13206 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13207 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13208 codec->chip_name);
a361d84b
KY
13209 board_config = ALC268_AUTO;
13210 }
13211
13212 if (board_config == ALC268_AUTO) {
13213 /* automatic parse from the BIOS config */
13214 err = alc268_parse_auto_config(codec);
13215 if (err < 0) {
13216 alc_free(codec);
13217 return err;
13218 } else if (!err) {
13219 printk(KERN_INFO
13220 "hda_codec: Cannot set up configuration "
13221 "from BIOS. Using base mode...\n");
13222 board_config = ALC268_3ST;
13223 }
13224 }
13225
13226 if (board_config != ALC268_AUTO)
e9c364c0 13227 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13228
a361d84b
KY
13229 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13230 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13231 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13232
a361d84b
KY
13233 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13234
22971e3a
TI
13235 has_beep = 0;
13236 for (i = 0; i < spec->num_mixers; i++) {
13237 if (spec->mixers[i] == alc268_beep_mixer) {
13238 has_beep = 1;
13239 break;
13240 }
13241 }
13242
13243 if (has_beep) {
13244 err = snd_hda_attach_beep_device(codec, 0x1);
13245 if (err < 0) {
13246 alc_free(codec);
13247 return err;
13248 }
13249 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13250 /* override the amp caps for beep generator */
13251 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13252 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13253 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13254 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13255 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13256 }
aef9d318 13257
7e0e44d4 13258 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13259 /* check whether NID 0x07 is valid */
13260 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13261 int i;
3866f0b0 13262
defb5ab2 13263 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13264 /* get type */
a22d543a 13265 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13266 if (spec->auto_mic ||
13267 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13268 spec->adc_nids = alc268_adc_nids_alt;
13269 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13270 if (spec->auto_mic)
13271 fixup_automic_adc(codec);
fdbc6626
TI
13272 if (spec->auto_mic || spec->input_mux->num_items == 1)
13273 add_mixer(spec, alc268_capture_nosrc_mixer);
13274 else
13275 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13276 } else {
13277 spec->adc_nids = alc268_adc_nids;
13278 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13279 add_mixer(spec, alc268_capture_mixer);
a361d84b 13280 }
85860c06
TI
13281 /* set default input source */
13282 for (i = 0; i < spec->num_adc_nids; i++)
13283 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13284 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13285 i < spec->num_mux_defs ?
13286 spec->input_mux[i].items[0].index :
85860c06 13287 spec->input_mux->items[0].index);
a361d84b 13288 }
2134ea4f
TI
13289
13290 spec->vmaster_nid = 0x02;
13291
a361d84b
KY
13292 codec->patch_ops = alc_patch_ops;
13293 if (board_config == ALC268_AUTO)
13294 spec->init_hook = alc268_auto_init;
ea1fb29a 13295
a361d84b
KY
13296 return 0;
13297}
13298
f6a92248
KY
13299/*
13300 * ALC269 channel source setting (2 channel)
13301 */
13302#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13303
13304#define alc269_dac_nids alc260_dac_nids
13305
13306static hda_nid_t alc269_adc_nids[1] = {
13307 /* ADC1 */
f53281e6
KY
13308 0x08,
13309};
13310
e01bf509
TI
13311static hda_nid_t alc269_capsrc_nids[1] = {
13312 0x23,
13313};
13314
84898e87
KY
13315static hda_nid_t alc269vb_adc_nids[1] = {
13316 /* ADC1 */
13317 0x09,
13318};
13319
13320static hda_nid_t alc269vb_capsrc_nids[1] = {
13321 0x22,
13322};
13323
e01bf509
TI
13324/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
13325 * not a mux!
13326 */
13327
f6a92248
KY
13328#define alc269_modes alc260_modes
13329#define alc269_capture_source alc880_lg_lw_capture_source
13330
13331static struct snd_kcontrol_new alc269_base_mixer[] = {
13332 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13333 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13334 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13335 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13338 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13339 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13340 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13341 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13342 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13343 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13344 { } /* end */
13345};
13346
60db6b53
KY
13347static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13348 /* output mixer control */
13349 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13350 {
13351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13352 .name = "Master Playback Switch",
5e26dfd0 13353 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13354 .info = snd_hda_mixer_amp_switch_info,
13355 .get = snd_hda_mixer_amp_switch_get,
13356 .put = alc268_acer_master_sw_put,
13357 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13358 },
13359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13361 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13362 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13363 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13364 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13365 { }
13366};
13367
64154835
TV
13368static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13369 /* output mixer control */
13370 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13371 {
13372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13373 .name = "Master Playback Switch",
5e26dfd0 13374 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13375 .info = snd_hda_mixer_amp_switch_info,
13376 .get = snd_hda_mixer_amp_switch_get,
13377 .put = alc268_acer_master_sw_put,
13378 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13379 },
13380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13381 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13382 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13383 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13384 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13385 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13386 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13387 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13388 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13389 { }
13390};
13391
84898e87 13392static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13393 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13396 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13397 { } /* end */
13398};
13399
84898e87
KY
13400static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13401 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13404 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13405 { } /* end */
13406};
13407
f53281e6 13408/* capture mixer elements */
84898e87
KY
13409static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13410 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13411 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13413 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13414 { } /* end */
13415};
13416
13417static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13421 { } /* end */
13422};
13423
84898e87
KY
13424static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13425 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13426 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13428 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13429 { } /* end */
13430};
13431
13432static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13433 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13434 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13436 { } /* end */
13437};
13438
26f5df26 13439/* FSC amilo */
84898e87 13440#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13441
60db6b53
KY
13442static struct hda_verb alc269_quanta_fl1_verbs[] = {
13443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13444 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13446 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13447 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13448 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13449 { }
13450};
f6a92248 13451
64154835
TV
13452static struct hda_verb alc269_lifebook_verbs[] = {
13453 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13454 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13455 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13457 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13459 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13460 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13461 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13462 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13463 { }
13464};
13465
60db6b53
KY
13466/* toggle speaker-output according to the hp-jack state */
13467static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13468{
13469 unsigned int present;
13470 unsigned char bits;
f6a92248 13471
864f92be 13472 present = snd_hda_jack_detect(codec, 0x15);
60db6b53
KY
13473 bits = present ? AMP_IN_MUTE(0) : 0;
13474 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13475 AMP_IN_MUTE(0), bits);
13476 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13477 AMP_IN_MUTE(0), bits);
f6a92248 13478
60db6b53
KY
13479 snd_hda_codec_write(codec, 0x20, 0,
13480 AC_VERB_SET_COEF_INDEX, 0x0c);
13481 snd_hda_codec_write(codec, 0x20, 0,
13482 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13483
60db6b53
KY
13484 snd_hda_codec_write(codec, 0x20, 0,
13485 AC_VERB_SET_COEF_INDEX, 0x0c);
13486 snd_hda_codec_write(codec, 0x20, 0,
13487 AC_VERB_SET_PROC_COEF, 0x480);
13488}
f6a92248 13489
64154835
TV
13490/* toggle speaker-output according to the hp-jacks state */
13491static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13492{
13493 unsigned int present;
13494 unsigned char bits;
13495
13496 /* Check laptop headphone socket */
864f92be 13497 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13498
13499 /* Check port replicator headphone socket */
864f92be 13500 present |= snd_hda_jack_detect(codec, 0x1a);
64154835
TV
13501
13502 bits = present ? AMP_IN_MUTE(0) : 0;
13503 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13504 AMP_IN_MUTE(0), bits);
13505 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13506 AMP_IN_MUTE(0), bits);
13507
13508 snd_hda_codec_write(codec, 0x20, 0,
13509 AC_VERB_SET_COEF_INDEX, 0x0c);
13510 snd_hda_codec_write(codec, 0x20, 0,
13511 AC_VERB_SET_PROC_COEF, 0x680);
13512
13513 snd_hda_codec_write(codec, 0x20, 0,
13514 AC_VERB_SET_COEF_INDEX, 0x0c);
13515 snd_hda_codec_write(codec, 0x20, 0,
13516 AC_VERB_SET_PROC_COEF, 0x480);
13517}
13518
64154835
TV
13519static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13520{
13521 unsigned int present_laptop;
13522 unsigned int present_dock;
13523
864f92be
WF
13524 present_laptop = snd_hda_jack_detect(codec, 0x18);
13525 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13526
13527 /* Laptop mic port overrides dock mic port, design decision */
13528 if (present_dock)
13529 snd_hda_codec_write(codec, 0x23, 0,
13530 AC_VERB_SET_CONNECT_SEL, 0x3);
13531 if (present_laptop)
13532 snd_hda_codec_write(codec, 0x23, 0,
13533 AC_VERB_SET_CONNECT_SEL, 0x0);
13534 if (!present_dock && !present_laptop)
13535 snd_hda_codec_write(codec, 0x23, 0,
13536 AC_VERB_SET_CONNECT_SEL, 0x1);
13537}
13538
60db6b53
KY
13539static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13540 unsigned int res)
13541{
4f5d1706
TI
13542 switch (res >> 26) {
13543 case ALC880_HP_EVENT:
60db6b53 13544 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13545 break;
13546 case ALC880_MIC_EVENT:
13547 alc_mic_automute(codec);
13548 break;
13549 }
60db6b53 13550}
f6a92248 13551
64154835
TV
13552static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13553 unsigned int res)
13554{
13555 if ((res >> 26) == ALC880_HP_EVENT)
13556 alc269_lifebook_speaker_automute(codec);
13557 if ((res >> 26) == ALC880_MIC_EVENT)
13558 alc269_lifebook_mic_autoswitch(codec);
13559}
13560
4f5d1706
TI
13561static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13562{
13563 struct alc_spec *spec = codec->spec;
20645d70
TI
13564 spec->autocfg.hp_pins[0] = 0x15;
13565 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13566 spec->ext_mic.pin = 0x18;
13567 spec->ext_mic.mux_idx = 0;
13568 spec->int_mic.pin = 0x19;
13569 spec->int_mic.mux_idx = 1;
13570 spec->auto_mic = 1;
13571}
13572
60db6b53
KY
13573static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13574{
13575 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13576 alc_mic_automute(codec);
60db6b53 13577}
f6a92248 13578
64154835
TV
13579static void alc269_lifebook_init_hook(struct hda_codec *codec)
13580{
13581 alc269_lifebook_speaker_automute(codec);
13582 alc269_lifebook_mic_autoswitch(codec);
13583}
13584
84898e87 13585static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
13586 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13587 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13588 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13589 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13590 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13591 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13593 {}
13594};
13595
84898e87 13596static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
13597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13598 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13599 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13600 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13601 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13602 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13603 {}
13604};
13605
84898e87
KY
13606static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13607 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13608 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13609 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13610 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13611 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13612 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13613 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13614 {}
13615};
13616
13617static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13618 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13619 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13620 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13622 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13623 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13624 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13625 {}
13626};
13627
f53281e6
KY
13628/* toggle speaker-output according to the hp-jack state */
13629static void alc269_speaker_automute(struct hda_codec *codec)
13630{
ebb83eeb
KY
13631 struct alc_spec *spec = codec->spec;
13632 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 13633 unsigned int present;
60db6b53 13634 unsigned char bits;
f53281e6 13635
ebb83eeb 13636 present = snd_hda_jack_detect(codec, nid);
f53281e6
KY
13637 bits = present ? AMP_IN_MUTE(0) : 0;
13638 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 13639 AMP_IN_MUTE(0), bits);
f53281e6 13640 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 13641 AMP_IN_MUTE(0), bits);
f53281e6
KY
13642}
13643
f53281e6 13644/* unsolicited event for HP jack sensing */
84898e87 13645static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 13646 unsigned int res)
f53281e6 13647{
4f5d1706
TI
13648 switch (res >> 26) {
13649 case ALC880_HP_EVENT:
f53281e6 13650 alc269_speaker_automute(codec);
4f5d1706
TI
13651 break;
13652 case ALC880_MIC_EVENT:
13653 alc_mic_automute(codec);
13654 break;
13655 }
f53281e6
KY
13656}
13657
84898e87 13658static void alc269_laptop_dmic_setup(struct hda_codec *codec)
f53281e6 13659{
4f5d1706 13660 struct alc_spec *spec = codec->spec;
20645d70
TI
13661 spec->autocfg.hp_pins[0] = 0x15;
13662 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13663 spec->ext_mic.pin = 0x18;
13664 spec->ext_mic.mux_idx = 0;
13665 spec->int_mic.pin = 0x12;
13666 spec->int_mic.mux_idx = 5;
13667 spec->auto_mic = 1;
f53281e6
KY
13668}
13669
84898e87
KY
13670static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13671{
13672 struct alc_spec *spec = codec->spec;
20645d70
TI
13673 spec->autocfg.hp_pins[0] = 0x15;
13674 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
13675 spec->ext_mic.pin = 0x18;
13676 spec->ext_mic.mux_idx = 0;
13677 spec->int_mic.pin = 0x12;
13678 spec->int_mic.mux_idx = 6;
13679 spec->auto_mic = 1;
13680}
13681
13682static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 13683{
4f5d1706 13684 struct alc_spec *spec = codec->spec;
20645d70
TI
13685 spec->autocfg.hp_pins[0] = 0x15;
13686 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13687 spec->ext_mic.pin = 0x18;
13688 spec->ext_mic.mux_idx = 0;
13689 spec->int_mic.pin = 0x19;
13690 spec->int_mic.mux_idx = 1;
13691 spec->auto_mic = 1;
f53281e6
KY
13692}
13693
84898e87 13694static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
13695{
13696 alc269_speaker_automute(codec);
4f5d1706 13697 alc_mic_automute(codec);
f53281e6
KY
13698}
13699
60db6b53
KY
13700/*
13701 * generic initialization of ADC, input mixers and output mixers
13702 */
13703static struct hda_verb alc269_init_verbs[] = {
13704 /*
13705 * Unmute ADC0 and set the default input to mic-in
13706 */
84898e87 13707 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
13708
13709 /*
84898e87 13710 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
13711 */
13712 /* set vol=0 to output mixers */
13713 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13714 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13715
13716 /* set up input amps for analog loopback */
13717 /* Amp Indices: DAC = 0, mixer = 1 */
13718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13724
13725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13727 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13728 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13730 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13731 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13732
13733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 13735
84898e87
KY
13736 /* FIXME: use Mux-type input source selection */
13737 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13738 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13739 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 13740
84898e87
KY
13741 /* set EAPD */
13742 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13743 { }
13744};
13745
13746static struct hda_verb alc269vb_init_verbs[] = {
13747 /*
13748 * Unmute ADC0 and set the default input to mic-in
13749 */
13750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13751
13752 /*
13753 * Set up output mixers (0x02 - 0x03)
13754 */
13755 /* set vol=0 to output mixers */
13756 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13757 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13758
13759 /* set up input amps for analog loopback */
13760 /* Amp Indices: DAC = 0, mixer = 1 */
13761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13762 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13763 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13764 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13767
13768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13769 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13770 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13771 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13772 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13774 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13775
13776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13777 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13778
13779 /* FIXME: use Mux-type input source selection */
60db6b53
KY
13780 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13781 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 13782 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
13783
13784 /* set EAPD */
13785 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
13786 { }
13787};
13788
9d0b71b1
TI
13789#define alc269_auto_create_multi_out_ctls \
13790 alc268_auto_create_multi_out_ctls
05f5f477
TI
13791#define alc269_auto_create_input_ctls \
13792 alc268_auto_create_input_ctls
f6a92248
KY
13793
13794#ifdef CONFIG_SND_HDA_POWER_SAVE
13795#define alc269_loopbacks alc880_loopbacks
13796#endif
13797
def319f9 13798/* pcm configuration: identical with ALC880 */
f6a92248
KY
13799#define alc269_pcm_analog_playback alc880_pcm_analog_playback
13800#define alc269_pcm_analog_capture alc880_pcm_analog_capture
13801#define alc269_pcm_digital_playback alc880_pcm_digital_playback
13802#define alc269_pcm_digital_capture alc880_pcm_digital_capture
13803
f03d3115
TI
13804static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13805 .substreams = 1,
13806 .channels_min = 2,
13807 .channels_max = 8,
13808 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13809 /* NID is set in alc_build_pcms */
13810 .ops = {
13811 .open = alc880_playback_pcm_open,
13812 .prepare = alc880_playback_pcm_prepare,
13813 .cleanup = alc880_playback_pcm_cleanup
13814 },
13815};
13816
13817static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13818 .substreams = 1,
13819 .channels_min = 2,
13820 .channels_max = 2,
13821 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13822 /* NID is set in alc_build_pcms */
13823};
13824
f6a92248
KY
13825/*
13826 * BIOS auto configuration
13827 */
13828static int alc269_parse_auto_config(struct hda_codec *codec)
13829{
13830 struct alc_spec *spec = codec->spec;
cfb9fb55 13831 int err;
f6a92248 13832 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
84898e87 13833 hda_nid_t real_capsrc_nids;
f6a92248
KY
13834
13835 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13836 alc269_ignore);
13837 if (err < 0)
13838 return err;
13839
13840 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13841 if (err < 0)
13842 return err;
05f5f477 13843 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
13844 if (err < 0)
13845 return err;
13846
13847 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13848
0852d7a6 13849 if (spec->autocfg.dig_outs)
f6a92248
KY
13850 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13851
603c4019 13852 if (spec->kctls.list)
d88897ea 13853 add_mixer(spec, spec->kctls.list);
f6a92248 13854
84898e87
KY
13855 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
13856 add_verb(spec, alc269vb_init_verbs);
13857 real_capsrc_nids = alc269vb_capsrc_nids[0];
6227cdce 13858 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
13859 } else {
13860 add_verb(spec, alc269_init_verbs);
13861 real_capsrc_nids = alc269_capsrc_nids[0];
6227cdce 13862 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
13863 }
13864
f6a92248 13865 spec->num_mux_defs = 1;
61b9b9b1 13866 spec->input_mux = &spec->private_imux[0];
e01bf509 13867 /* set default input source */
84898e87 13868 snd_hda_codec_write_cache(codec, real_capsrc_nids,
e01bf509
TI
13869 0, AC_VERB_SET_CONNECT_SEL,
13870 spec->input_mux->items[0].index);
f6a92248
KY
13871
13872 err = alc_auto_add_mic_boost(codec);
13873 if (err < 0)
13874 return err;
13875
7e0e44d4 13876 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13877 set_capture_mixer(codec);
f53281e6 13878
f6a92248
KY
13879 return 1;
13880}
13881
e9af4f36
TI
13882#define alc269_auto_init_multi_out alc268_auto_init_multi_out
13883#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
13884#define alc269_auto_init_analog_input alc882_auto_init_analog_input
13885
13886
13887/* init callback for auto-configuration model -- overriding the default init */
13888static void alc269_auto_init(struct hda_codec *codec)
13889{
f6c7e546 13890 struct alc_spec *spec = codec->spec;
f6a92248
KY
13891 alc269_auto_init_multi_out(codec);
13892 alc269_auto_init_hp_out(codec);
13893 alc269_auto_init_analog_input(codec);
f6c7e546 13894 if (spec->unsol_event)
7fb0d78f 13895 alc_inithook(codec);
f6a92248
KY
13896}
13897
13898/*
13899 * configuration and preset
13900 */
13901static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 13902 [ALC269_BASIC] = "basic",
2922c9af 13903 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
13904 [ALC269_AMIC] = "laptop-amic",
13905 [ALC269_DMIC] = "laptop-dmic",
64154835 13906 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
13907 [ALC269_LIFEBOOK] = "lifebook",
13908 [ALC269_AUTO] = "auto",
f6a92248
KY
13909};
13910
13911static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 13912 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 13913 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
13914 ALC269_AMIC),
13915 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
13916 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
13917 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
13918 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
13919 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
13920 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
13921 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
13922 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
13923 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
13924 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
13925 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
13926 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
13927 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
13928 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
13929 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
13930 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
13931 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
13932 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
13933 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
13934 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
13935 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
13936 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
13937 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
13938 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
13939 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
13940 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
13941 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
13942 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
13943 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
13944 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
13945 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
13946 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
13947 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
13948 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
13949 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
13950 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 13951 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 13952 ALC269_DMIC),
60db6b53 13953 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
13954 ALC269_DMIC),
13955 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13956 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
61c2d2b5 13957 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
64154835 13958 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
13959 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
13960 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13961 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
13962 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
13963 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
13964 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
13965 {}
13966};
13967
13968static struct alc_config_preset alc269_presets[] = {
13969 [ALC269_BASIC] = {
f9e336f6 13970 .mixers = { alc269_base_mixer },
f6a92248
KY
13971 .init_verbs = { alc269_init_verbs },
13972 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13973 .dac_nids = alc269_dac_nids,
13974 .hp_nid = 0x03,
13975 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13976 .channel_mode = alc269_modes,
13977 .input_mux = &alc269_capture_source,
13978 },
60db6b53
KY
13979 [ALC269_QUANTA_FL1] = {
13980 .mixers = { alc269_quanta_fl1_mixer },
13981 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13982 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13983 .dac_nids = alc269_dac_nids,
13984 .hp_nid = 0x03,
13985 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13986 .channel_mode = alc269_modes,
13987 .input_mux = &alc269_capture_source,
13988 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 13989 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
13990 .init_hook = alc269_quanta_fl1_init_hook,
13991 },
84898e87
KY
13992 [ALC269_AMIC] = {
13993 .mixers = { alc269_laptop_mixer },
13994 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 13995 .init_verbs = { alc269_init_verbs,
84898e87 13996 alc269_laptop_amic_init_verbs },
f53281e6
KY
13997 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13998 .dac_nids = alc269_dac_nids,
13999 .hp_nid = 0x03,
14000 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14001 .channel_mode = alc269_modes,
84898e87
KY
14002 .unsol_event = alc269_laptop_unsol_event,
14003 .setup = alc269_laptop_amic_setup,
14004 .init_hook = alc269_laptop_inithook,
f53281e6 14005 },
84898e87
KY
14006 [ALC269_DMIC] = {
14007 .mixers = { alc269_laptop_mixer },
14008 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14009 .init_verbs = { alc269_init_verbs,
84898e87
KY
14010 alc269_laptop_dmic_init_verbs },
14011 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14012 .dac_nids = alc269_dac_nids,
14013 .hp_nid = 0x03,
14014 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14015 .channel_mode = alc269_modes,
14016 .unsol_event = alc269_laptop_unsol_event,
14017 .setup = alc269_laptop_dmic_setup,
14018 .init_hook = alc269_laptop_inithook,
14019 },
14020 [ALC269VB_AMIC] = {
14021 .mixers = { alc269vb_laptop_mixer },
14022 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14023 .init_verbs = { alc269vb_init_verbs,
14024 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14025 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14026 .dac_nids = alc269_dac_nids,
14027 .hp_nid = 0x03,
14028 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14029 .channel_mode = alc269_modes,
84898e87
KY
14030 .unsol_event = alc269_laptop_unsol_event,
14031 .setup = alc269_laptop_amic_setup,
14032 .init_hook = alc269_laptop_inithook,
14033 },
14034 [ALC269VB_DMIC] = {
14035 .mixers = { alc269vb_laptop_mixer },
14036 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14037 .init_verbs = { alc269vb_init_verbs,
14038 alc269vb_laptop_dmic_init_verbs },
14039 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14040 .dac_nids = alc269_dac_nids,
14041 .hp_nid = 0x03,
14042 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14043 .channel_mode = alc269_modes,
14044 .unsol_event = alc269_laptop_unsol_event,
14045 .setup = alc269vb_laptop_dmic_setup,
14046 .init_hook = alc269_laptop_inithook,
f53281e6 14047 },
26f5df26 14048 [ALC269_FUJITSU] = {
45bdd1c1 14049 .mixers = { alc269_fujitsu_mixer },
84898e87 14050 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14051 .init_verbs = { alc269_init_verbs,
84898e87 14052 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14053 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14054 .dac_nids = alc269_dac_nids,
14055 .hp_nid = 0x03,
14056 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14057 .channel_mode = alc269_modes,
84898e87
KY
14058 .unsol_event = alc269_laptop_unsol_event,
14059 .setup = alc269_laptop_dmic_setup,
14060 .init_hook = alc269_laptop_inithook,
26f5df26 14061 },
64154835
TV
14062 [ALC269_LIFEBOOK] = {
14063 .mixers = { alc269_lifebook_mixer },
14064 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14065 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14066 .dac_nids = alc269_dac_nids,
14067 .hp_nid = 0x03,
14068 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14069 .channel_mode = alc269_modes,
14070 .input_mux = &alc269_capture_source,
14071 .unsol_event = alc269_lifebook_unsol_event,
14072 .init_hook = alc269_lifebook_init_hook,
14073 },
f6a92248
KY
14074};
14075
14076static int patch_alc269(struct hda_codec *codec)
14077{
14078 struct alc_spec *spec;
14079 int board_config;
14080 int err;
84898e87 14081 int is_alc269vb = 0;
f6a92248
KY
14082
14083 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14084 if (spec == NULL)
14085 return -ENOMEM;
14086
14087 codec->spec = spec;
14088
2c3bf9ab
TI
14089 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14090
274693f3
KY
14091 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14092 kfree(codec->chip_name);
14093 codec->chip_name = kstrdup("ALC259", GFP_KERNEL);
ac2c92e0
TI
14094 if (!codec->chip_name) {
14095 alc_free(codec);
274693f3 14096 return -ENOMEM;
ac2c92e0 14097 }
84898e87 14098 is_alc269vb = 1;
274693f3
KY
14099 }
14100
f6a92248
KY
14101 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14102 alc269_models,
14103 alc269_cfg_tbl);
14104
14105 if (board_config < 0) {
9a11f1aa
TI
14106 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14107 codec->chip_name);
f6a92248
KY
14108 board_config = ALC269_AUTO;
14109 }
14110
14111 if (board_config == ALC269_AUTO) {
14112 /* automatic parse from the BIOS config */
14113 err = alc269_parse_auto_config(codec);
14114 if (err < 0) {
14115 alc_free(codec);
14116 return err;
14117 } else if (!err) {
14118 printk(KERN_INFO
14119 "hda_codec: Cannot set up configuration "
14120 "from BIOS. Using base mode...\n");
14121 board_config = ALC269_BASIC;
14122 }
14123 }
14124
680cd536
KK
14125 err = snd_hda_attach_beep_device(codec, 0x1);
14126 if (err < 0) {
14127 alc_free(codec);
14128 return err;
14129 }
14130
f6a92248 14131 if (board_config != ALC269_AUTO)
e9c364c0 14132 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14133
84898e87 14134 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14135 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14136 * fix the sample rate of analog I/O to 44.1kHz
14137 */
14138 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14139 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14140 } else {
14141 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14142 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14143 }
f6a92248
KY
14144 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14145 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14146
84898e87
KY
14147 if (!is_alc269vb) {
14148 spec->adc_nids = alc269_adc_nids;
14149 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14150 spec->capsrc_nids = alc269_capsrc_nids;
14151 } else {
14152 spec->adc_nids = alc269vb_adc_nids;
14153 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14154 spec->capsrc_nids = alc269vb_capsrc_nids;
14155 }
14156
f9e336f6 14157 if (!spec->cap_mixer)
b59bdf3b 14158 set_capture_mixer(codec);
45bdd1c1 14159 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14160
100d5eb3
TI
14161 spec->vmaster_nid = 0x02;
14162
f6a92248
KY
14163 codec->patch_ops = alc_patch_ops;
14164 if (board_config == ALC269_AUTO)
14165 spec->init_hook = alc269_auto_init;
14166#ifdef CONFIG_SND_HDA_POWER_SAVE
14167 if (!spec->loopback.amplist)
14168 spec->loopback.amplist = alc269_loopbacks;
14169#endif
14170
14171 return 0;
14172}
14173
df694daa
KY
14174/*
14175 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14176 */
14177
14178/*
14179 * set the path ways for 2 channel output
14180 * need to set the codec line out and mic 1 pin widgets to inputs
14181 */
14182static struct hda_verb alc861_threestack_ch2_init[] = {
14183 /* set pin widget 1Ah (line in) for input */
14184 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14185 /* set pin widget 18h (mic1/2) for input, for mic also enable
14186 * the vref
14187 */
df694daa
KY
14188 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14189
9c7f852e
TI
14190 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14191#if 0
14192 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14193 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14194#endif
df694daa
KY
14195 { } /* end */
14196};
14197/*
14198 * 6ch mode
14199 * need to set the codec line out and mic 1 pin widgets to outputs
14200 */
14201static struct hda_verb alc861_threestack_ch6_init[] = {
14202 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14203 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14204 /* set pin widget 18h (mic1) for output (CLFE)*/
14205 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14206
14207 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14208 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14209
9c7f852e
TI
14210 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14211#if 0
14212 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14213 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14214#endif
df694daa
KY
14215 { } /* end */
14216};
14217
14218static struct hda_channel_mode alc861_threestack_modes[2] = {
14219 { 2, alc861_threestack_ch2_init },
14220 { 6, alc861_threestack_ch6_init },
14221};
22309c3e
TI
14222/* Set mic1 as input and unmute the mixer */
14223static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14224 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14225 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14226 { } /* end */
14227};
14228/* Set mic1 as output and mute mixer */
14229static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14230 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14231 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14232 { } /* end */
14233};
14234
14235static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14236 { 2, alc861_uniwill_m31_ch2_init },
14237 { 4, alc861_uniwill_m31_ch4_init },
14238};
df694daa 14239
7cdbff94
MD
14240/* Set mic1 and line-in as input and unmute the mixer */
14241static struct hda_verb alc861_asus_ch2_init[] = {
14242 /* set pin widget 1Ah (line in) for input */
14243 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14244 /* set pin widget 18h (mic1/2) for input, for mic also enable
14245 * the vref
14246 */
7cdbff94
MD
14247 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14248
14249 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14250#if 0
14251 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14252 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14253#endif
14254 { } /* end */
14255};
14256/* Set mic1 nad line-in as output and mute mixer */
14257static struct hda_verb alc861_asus_ch6_init[] = {
14258 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14259 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14260 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14261 /* set pin widget 18h (mic1) for output (CLFE)*/
14262 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14263 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14264 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14265 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14266
14267 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14268#if 0
14269 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14270 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14271#endif
14272 { } /* end */
14273};
14274
14275static struct hda_channel_mode alc861_asus_modes[2] = {
14276 { 2, alc861_asus_ch2_init },
14277 { 6, alc861_asus_ch6_init },
14278};
14279
df694daa
KY
14280/* patch-ALC861 */
14281
14282static struct snd_kcontrol_new alc861_base_mixer[] = {
14283 /* output mixer control */
14284 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14285 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14286 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14287 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14288 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14289
14290 /*Input mixer control */
14291 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14292 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14293 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14294 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14295 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14296 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14298 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14299 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14300 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14301
df694daa
KY
14302 { } /* end */
14303};
14304
14305static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14306 /* output mixer control */
14307 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14308 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14309 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14310 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14311 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14312
14313 /* Input mixer control */
14314 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14315 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14316 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14317 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14318 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14319 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14321 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14322 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14324
df694daa
KY
14325 {
14326 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14327 .name = "Channel Mode",
14328 .info = alc_ch_mode_info,
14329 .get = alc_ch_mode_get,
14330 .put = alc_ch_mode_put,
14331 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14332 },
14333 { } /* end */
a53d1aec
TD
14334};
14335
d1d985f0 14336static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14337 /* output mixer control */
14338 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14339 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14340 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14341
a53d1aec 14342 { } /* end */
f12ab1e0 14343};
a53d1aec 14344
22309c3e
TI
14345static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14346 /* output mixer control */
14347 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14348 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14349 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14350 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14351 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14352
14353 /* Input mixer control */
14354 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14355 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14356 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14357 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14358 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14359 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14361 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14362 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14363 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14364
22309c3e
TI
14365 {
14366 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14367 .name = "Channel Mode",
14368 .info = alc_ch_mode_info,
14369 .get = alc_ch_mode_get,
14370 .put = alc_ch_mode_put,
14371 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14372 },
14373 { } /* end */
f12ab1e0 14374};
7cdbff94
MD
14375
14376static struct snd_kcontrol_new alc861_asus_mixer[] = {
14377 /* output mixer control */
14378 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14379 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14380 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14381 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14382 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14383
14384 /* Input mixer control */
14385 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14386 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14387 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14388 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14389 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14390 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14392 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14393 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14394 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14395
7cdbff94
MD
14396 {
14397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14398 .name = "Channel Mode",
14399 .info = alc_ch_mode_info,
14400 .get = alc_ch_mode_get,
14401 .put = alc_ch_mode_put,
14402 .private_value = ARRAY_SIZE(alc861_asus_modes),
14403 },
14404 { }
56bb0cab
TI
14405};
14406
14407/* additional mixer */
d1d985f0 14408static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14409 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14410 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14411 { }
14412};
7cdbff94 14413
df694daa
KY
14414/*
14415 * generic initialization of ADC, input mixers and output mixers
14416 */
14417static struct hda_verb alc861_base_init_verbs[] = {
14418 /*
14419 * Unmute ADC0 and set the default input to mic-in
14420 */
14421 /* port-A for surround (rear panel) */
14422 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14423 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14424 /* port-B for mic-in (rear panel) with vref */
14425 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14426 /* port-C for line-in (rear panel) */
14427 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14428 /* port-D for Front */
14429 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14430 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14431 /* port-E for HP out (front panel) */
14432 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14433 /* route front PCM to HP */
9dece1d7 14434 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14435 /* port-F for mic-in (front panel) with vref */
14436 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14437 /* port-G for CLFE (rear panel) */
14438 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14439 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14440 /* port-H for side (rear panel) */
14441 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14442 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14443 /* CD-in */
14444 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14445 /* route front mic to ADC1*/
14446 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14447 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14448
df694daa
KY
14449 /* Unmute DAC0~3 & spdif out*/
14450 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14451 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14452 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14453 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14455
df694daa
KY
14456 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14457 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14458 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14459 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14460 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14461
df694daa
KY
14462 /* Unmute Stereo Mixer 15 */
14463 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14465 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14466 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14467
14468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14469 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14470 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14471 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14472 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14473 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14474 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14475 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14476 /* hp used DAC 3 (Front) */
14477 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14478 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14479
14480 { }
14481};
14482
14483static struct hda_verb alc861_threestack_init_verbs[] = {
14484 /*
14485 * Unmute ADC0 and set the default input to mic-in
14486 */
14487 /* port-A for surround (rear panel) */
14488 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14489 /* port-B for mic-in (rear panel) with vref */
14490 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14491 /* port-C for line-in (rear panel) */
14492 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14493 /* port-D for Front */
14494 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14495 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14496 /* port-E for HP out (front panel) */
14497 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14498 /* route front PCM to HP */
9dece1d7 14499 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14500 /* port-F for mic-in (front panel) with vref */
14501 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14502 /* port-G for CLFE (rear panel) */
14503 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14504 /* port-H for side (rear panel) */
14505 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14506 /* CD-in */
14507 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14508 /* route front mic to ADC1*/
14509 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14510 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14511 /* Unmute DAC0~3 & spdif out*/
14512 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14513 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14514 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14515 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14517
df694daa
KY
14518 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14519 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14520 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14521 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14522 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14523
df694daa
KY
14524 /* Unmute Stereo Mixer 15 */
14525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14526 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14528 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14529
14530 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14531 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14532 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14533 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14535 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14536 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14537 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14538 /* hp used DAC 3 (Front) */
14539 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14540 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14541 { }
14542};
22309c3e
TI
14543
14544static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14545 /*
14546 * Unmute ADC0 and set the default input to mic-in
14547 */
14548 /* port-A for surround (rear panel) */
14549 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14550 /* port-B for mic-in (rear panel) with vref */
14551 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14552 /* port-C for line-in (rear panel) */
14553 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14554 /* port-D for Front */
14555 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14556 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14557 /* port-E for HP out (front panel) */
f12ab1e0
TI
14558 /* this has to be set to VREF80 */
14559 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 14560 /* route front PCM to HP */
9dece1d7 14561 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
14562 /* port-F for mic-in (front panel) with vref */
14563 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14564 /* port-G for CLFE (rear panel) */
14565 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14566 /* port-H for side (rear panel) */
14567 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14568 /* CD-in */
14569 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14570 /* route front mic to ADC1*/
14571 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14573 /* Unmute DAC0~3 & spdif out*/
14574 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14575 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14576 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14577 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14579
22309c3e
TI
14580 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14581 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14582 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14583 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14584 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14585
22309c3e
TI
14586 /* Unmute Stereo Mixer 15 */
14587 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14588 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
14591
14592 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14593 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14594 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14595 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14597 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14599 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14600 /* hp used DAC 3 (Front) */
14601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
14602 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14603 { }
14604};
14605
7cdbff94
MD
14606static struct hda_verb alc861_asus_init_verbs[] = {
14607 /*
14608 * Unmute ADC0 and set the default input to mic-in
14609 */
f12ab1e0
TI
14610 /* port-A for surround (rear panel)
14611 * according to codec#0 this is the HP jack
14612 */
7cdbff94
MD
14613 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14614 /* route front PCM to HP */
14615 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14616 /* port-B for mic-in (rear panel) with vref */
14617 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14618 /* port-C for line-in (rear panel) */
14619 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14620 /* port-D for Front */
14621 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14622 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14623 /* port-E for HP out (front panel) */
f12ab1e0
TI
14624 /* this has to be set to VREF80 */
14625 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 14626 /* route front PCM to HP */
9dece1d7 14627 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
14628 /* port-F for mic-in (front panel) with vref */
14629 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14630 /* port-G for CLFE (rear panel) */
14631 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14632 /* port-H for side (rear panel) */
14633 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14634 /* CD-in */
14635 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14636 /* route front mic to ADC1*/
14637 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14639 /* Unmute DAC0~3 & spdif out*/
14640 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14641 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14642 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14643 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14645 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14646 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14647 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14648 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14649 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14650
7cdbff94
MD
14651 /* Unmute Stereo Mixer 15 */
14652 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
14656
14657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14658 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14659 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14660 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14661 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14662 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14663 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14664 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14665 /* hp used DAC 3 (Front) */
14666 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
14667 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14668 { }
14669};
14670
56bb0cab
TI
14671/* additional init verbs for ASUS laptops */
14672static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14673 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14674 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14675 { }
14676};
7cdbff94 14677
df694daa
KY
14678/*
14679 * generic initialization of ADC, input mixers and output mixers
14680 */
14681static struct hda_verb alc861_auto_init_verbs[] = {
14682 /*
14683 * Unmute ADC0 and set the default input to mic-in
14684 */
f12ab1e0 14685 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 14686 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14687
df694daa
KY
14688 /* Unmute DAC0~3 & spdif out*/
14689 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14690 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14691 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14692 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14694
df694daa
KY
14695 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14696 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14697 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14698 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14699 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14700
df694daa
KY
14701 /* Unmute Stereo Mixer 15 */
14702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14704 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14706
1c20930a
TI
14707 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14708 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14709 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14710 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14711 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14712 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14714 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
14715
14716 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14717 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14718 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14719 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
14720 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14721 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14722 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14723 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 14724
f12ab1e0 14725 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
14726
14727 { }
14728};
14729
a53d1aec
TD
14730static struct hda_verb alc861_toshiba_init_verbs[] = {
14731 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 14732
a53d1aec
TD
14733 { }
14734};
14735
14736/* toggle speaker-output according to the hp-jack state */
14737static void alc861_toshiba_automute(struct hda_codec *codec)
14738{
864f92be 14739 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 14740
47fd830a
TI
14741 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14742 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14743 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14744 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
14745}
14746
14747static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14748 unsigned int res)
14749{
a53d1aec
TD
14750 if ((res >> 26) == ALC880_HP_EVENT)
14751 alc861_toshiba_automute(codec);
14752}
14753
def319f9 14754/* pcm configuration: identical with ALC880 */
df694daa
KY
14755#define alc861_pcm_analog_playback alc880_pcm_analog_playback
14756#define alc861_pcm_analog_capture alc880_pcm_analog_capture
14757#define alc861_pcm_digital_playback alc880_pcm_digital_playback
14758#define alc861_pcm_digital_capture alc880_pcm_digital_capture
14759
14760
14761#define ALC861_DIGOUT_NID 0x07
14762
14763static struct hda_channel_mode alc861_8ch_modes[1] = {
14764 { 8, NULL }
14765};
14766
14767static hda_nid_t alc861_dac_nids[4] = {
14768 /* front, surround, clfe, side */
14769 0x03, 0x06, 0x05, 0x04
14770};
14771
9c7f852e
TI
14772static hda_nid_t alc660_dac_nids[3] = {
14773 /* front, clfe, surround */
14774 0x03, 0x05, 0x06
14775};
14776
df694daa
KY
14777static hda_nid_t alc861_adc_nids[1] = {
14778 /* ADC0-2 */
14779 0x08,
14780};
14781
14782static struct hda_input_mux alc861_capture_source = {
14783 .num_items = 5,
14784 .items = {
14785 { "Mic", 0x0 },
14786 { "Front Mic", 0x3 },
14787 { "Line", 0x1 },
14788 { "CD", 0x4 },
14789 { "Mixer", 0x5 },
14790 },
14791};
14792
1c20930a
TI
14793static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14794{
14795 struct alc_spec *spec = codec->spec;
14796 hda_nid_t mix, srcs[5];
14797 int i, j, num;
14798
14799 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14800 return 0;
14801 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14802 if (num < 0)
14803 return 0;
14804 for (i = 0; i < num; i++) {
14805 unsigned int type;
a22d543a 14806 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
14807 if (type != AC_WID_AUD_OUT)
14808 continue;
14809 for (j = 0; j < spec->multiout.num_dacs; j++)
14810 if (spec->multiout.dac_nids[j] == srcs[i])
14811 break;
14812 if (j >= spec->multiout.num_dacs)
14813 return srcs[i];
14814 }
14815 return 0;
14816}
14817
df694daa 14818/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 14819static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 14820 const struct auto_pin_cfg *cfg)
df694daa 14821{
1c20930a 14822 struct alc_spec *spec = codec->spec;
df694daa 14823 int i;
1c20930a 14824 hda_nid_t nid, dac;
df694daa
KY
14825
14826 spec->multiout.dac_nids = spec->private_dac_nids;
14827 for (i = 0; i < cfg->line_outs; i++) {
14828 nid = cfg->line_out_pins[i];
1c20930a
TI
14829 dac = alc861_look_for_dac(codec, nid);
14830 if (!dac)
14831 continue;
14832 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 14833 }
df694daa
KY
14834 return 0;
14835}
14836
1c20930a
TI
14837static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14838 hda_nid_t nid, unsigned int chs)
14839{
0afe5f89 14840 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
14841 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14842}
14843
df694daa 14844/* add playback controls from the parsed DAC table */
1c20930a 14845static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
14846 const struct auto_pin_cfg *cfg)
14847{
1c20930a 14848 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
14849 static const char *chname[4] = {
14850 "Front", "Surround", NULL /*CLFE*/, "Side"
14851 };
df694daa 14852 hda_nid_t nid;
1c20930a
TI
14853 int i, err;
14854
14855 if (cfg->line_outs == 1) {
14856 const char *pfx = NULL;
14857 if (!cfg->hp_outs)
14858 pfx = "Master";
14859 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14860 pfx = "Speaker";
14861 if (pfx) {
14862 nid = spec->multiout.dac_nids[0];
14863 return alc861_create_out_sw(codec, pfx, nid, 3);
14864 }
14865 }
df694daa
KY
14866
14867 for (i = 0; i < cfg->line_outs; i++) {
14868 nid = spec->multiout.dac_nids[i];
f12ab1e0 14869 if (!nid)
df694daa 14870 continue;
1c20930a 14871 if (i == 2) {
df694daa 14872 /* Center/LFE */
1c20930a 14873 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 14874 if (err < 0)
df694daa 14875 return err;
1c20930a 14876 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 14877 if (err < 0)
df694daa
KY
14878 return err;
14879 } else {
1c20930a 14880 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 14881 if (err < 0)
df694daa
KY
14882 return err;
14883 }
14884 }
14885 return 0;
14886}
14887
1c20930a 14888static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 14889{
1c20930a 14890 struct alc_spec *spec = codec->spec;
df694daa
KY
14891 int err;
14892 hda_nid_t nid;
14893
f12ab1e0 14894 if (!pin)
df694daa
KY
14895 return 0;
14896
14897 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
14898 nid = alc861_look_for_dac(codec, pin);
14899 if (nid) {
14900 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14901 if (err < 0)
14902 return err;
14903 spec->multiout.hp_nid = nid;
14904 }
df694daa
KY
14905 }
14906 return 0;
14907}
14908
14909/* create playback/capture controls for input pins */
05f5f477 14910static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 14911 const struct auto_pin_cfg *cfg)
df694daa 14912{
05f5f477 14913 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
14914}
14915
f12ab1e0
TI
14916static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14917 hda_nid_t nid,
1c20930a 14918 int pin_type, hda_nid_t dac)
df694daa 14919{
1c20930a
TI
14920 hda_nid_t mix, srcs[5];
14921 int i, num;
14922
564c5bea
JL
14923 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14924 pin_type);
1c20930a 14925 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 14926 AMP_OUT_UNMUTE);
1c20930a
TI
14927 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14928 return;
14929 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14930 if (num < 0)
14931 return;
14932 for (i = 0; i < num; i++) {
14933 unsigned int mute;
14934 if (srcs[i] == dac || srcs[i] == 0x15)
14935 mute = AMP_IN_UNMUTE(i);
14936 else
14937 mute = AMP_IN_MUTE(i);
14938 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14939 mute);
14940 }
df694daa
KY
14941}
14942
14943static void alc861_auto_init_multi_out(struct hda_codec *codec)
14944{
14945 struct alc_spec *spec = codec->spec;
14946 int i;
14947
14948 for (i = 0; i < spec->autocfg.line_outs; i++) {
14949 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14950 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 14951 if (nid)
baba8ee9 14952 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 14953 spec->multiout.dac_nids[i]);
df694daa
KY
14954 }
14955}
14956
14957static void alc861_auto_init_hp_out(struct hda_codec *codec)
14958{
14959 struct alc_spec *spec = codec->spec;
df694daa 14960
15870f05
TI
14961 if (spec->autocfg.hp_outs)
14962 alc861_auto_set_output_and_unmute(codec,
14963 spec->autocfg.hp_pins[0],
14964 PIN_HP,
1c20930a 14965 spec->multiout.hp_nid);
15870f05
TI
14966 if (spec->autocfg.speaker_outs)
14967 alc861_auto_set_output_and_unmute(codec,
14968 spec->autocfg.speaker_pins[0],
14969 PIN_OUT,
1c20930a 14970 spec->multiout.dac_nids[0]);
df694daa
KY
14971}
14972
14973static void alc861_auto_init_analog_input(struct hda_codec *codec)
14974{
14975 struct alc_spec *spec = codec->spec;
14976 int i;
14977
14978 for (i = 0; i < AUTO_PIN_LAST; i++) {
14979 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
14980 if (nid >= 0x0c && nid <= 0x11)
14981 alc_set_input_pin(codec, nid, i);
df694daa
KY
14982 }
14983}
14984
14985/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
14986/* return 1 if successful, 0 if the proper config is not found,
14987 * or a negative error code
14988 */
df694daa
KY
14989static int alc861_parse_auto_config(struct hda_codec *codec)
14990{
14991 struct alc_spec *spec = codec->spec;
14992 int err;
14993 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14994
f12ab1e0
TI
14995 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14996 alc861_ignore);
14997 if (err < 0)
df694daa 14998 return err;
f12ab1e0 14999 if (!spec->autocfg.line_outs)
df694daa
KY
15000 return 0; /* can't find valid BIOS pin config */
15001
1c20930a 15002 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15003 if (err < 0)
15004 return err;
1c20930a 15005 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15006 if (err < 0)
15007 return err;
1c20930a 15008 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15009 if (err < 0)
15010 return err;
05f5f477 15011 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15012 if (err < 0)
df694daa
KY
15013 return err;
15014
15015 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15016
0852d7a6 15017 if (spec->autocfg.dig_outs)
df694daa
KY
15018 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15019
603c4019 15020 if (spec->kctls.list)
d88897ea 15021 add_mixer(spec, spec->kctls.list);
df694daa 15022
d88897ea 15023 add_verb(spec, alc861_auto_init_verbs);
df694daa 15024
a1e8d2da 15025 spec->num_mux_defs = 1;
61b9b9b1 15026 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15027
15028 spec->adc_nids = alc861_adc_nids;
15029 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15030 set_capture_mixer(codec);
df694daa 15031
6227cdce 15032 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15033
df694daa
KY
15034 return 1;
15035}
15036
ae6b813a
TI
15037/* additional initialization for auto-configuration model */
15038static void alc861_auto_init(struct hda_codec *codec)
df694daa 15039{
f6c7e546 15040 struct alc_spec *spec = codec->spec;
df694daa
KY
15041 alc861_auto_init_multi_out(codec);
15042 alc861_auto_init_hp_out(codec);
15043 alc861_auto_init_analog_input(codec);
f6c7e546 15044 if (spec->unsol_event)
7fb0d78f 15045 alc_inithook(codec);
df694daa
KY
15046}
15047
cb53c626
TI
15048#ifdef CONFIG_SND_HDA_POWER_SAVE
15049static struct hda_amp_list alc861_loopbacks[] = {
15050 { 0x15, HDA_INPUT, 0 },
15051 { 0x15, HDA_INPUT, 1 },
15052 { 0x15, HDA_INPUT, 2 },
15053 { 0x15, HDA_INPUT, 3 },
15054 { } /* end */
15055};
15056#endif
15057
df694daa
KY
15058
15059/*
15060 * configuration and preset
15061 */
f5fcc13c
TI
15062static const char *alc861_models[ALC861_MODEL_LAST] = {
15063 [ALC861_3ST] = "3stack",
15064 [ALC660_3ST] = "3stack-660",
15065 [ALC861_3ST_DIG] = "3stack-dig",
15066 [ALC861_6ST_DIG] = "6stack-dig",
15067 [ALC861_UNIWILL_M31] = "uniwill-m31",
15068 [ALC861_TOSHIBA] = "toshiba",
15069 [ALC861_ASUS] = "asus",
15070 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15071 [ALC861_AUTO] = "auto",
15072};
15073
15074static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15075 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15076 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15077 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15078 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15079 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15080 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15081 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15082 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15083 * Any other models that need this preset?
15084 */
15085 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15086 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15087 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15088 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15089 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15090 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15091 /* FIXME: the below seems conflict */
15092 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15093 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15094 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15095 {}
15096};
15097
15098static struct alc_config_preset alc861_presets[] = {
15099 [ALC861_3ST] = {
15100 .mixers = { alc861_3ST_mixer },
15101 .init_verbs = { alc861_threestack_init_verbs },
15102 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15103 .dac_nids = alc861_dac_nids,
15104 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15105 .channel_mode = alc861_threestack_modes,
4e195a7b 15106 .need_dac_fix = 1,
df694daa
KY
15107 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15108 .adc_nids = alc861_adc_nids,
15109 .input_mux = &alc861_capture_source,
15110 },
15111 [ALC861_3ST_DIG] = {
15112 .mixers = { alc861_base_mixer },
15113 .init_verbs = { alc861_threestack_init_verbs },
15114 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15115 .dac_nids = alc861_dac_nids,
15116 .dig_out_nid = ALC861_DIGOUT_NID,
15117 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15118 .channel_mode = alc861_threestack_modes,
4e195a7b 15119 .need_dac_fix = 1,
df694daa
KY
15120 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15121 .adc_nids = alc861_adc_nids,
15122 .input_mux = &alc861_capture_source,
15123 },
15124 [ALC861_6ST_DIG] = {
15125 .mixers = { alc861_base_mixer },
15126 .init_verbs = { alc861_base_init_verbs },
15127 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15128 .dac_nids = alc861_dac_nids,
15129 .dig_out_nid = ALC861_DIGOUT_NID,
15130 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15131 .channel_mode = alc861_8ch_modes,
15132 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15133 .adc_nids = alc861_adc_nids,
15134 .input_mux = &alc861_capture_source,
15135 },
9c7f852e
TI
15136 [ALC660_3ST] = {
15137 .mixers = { alc861_3ST_mixer },
15138 .init_verbs = { alc861_threestack_init_verbs },
15139 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15140 .dac_nids = alc660_dac_nids,
15141 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15142 .channel_mode = alc861_threestack_modes,
4e195a7b 15143 .need_dac_fix = 1,
9c7f852e
TI
15144 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15145 .adc_nids = alc861_adc_nids,
15146 .input_mux = &alc861_capture_source,
15147 },
22309c3e
TI
15148 [ALC861_UNIWILL_M31] = {
15149 .mixers = { alc861_uniwill_m31_mixer },
15150 .init_verbs = { alc861_uniwill_m31_init_verbs },
15151 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15152 .dac_nids = alc861_dac_nids,
15153 .dig_out_nid = ALC861_DIGOUT_NID,
15154 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15155 .channel_mode = alc861_uniwill_m31_modes,
15156 .need_dac_fix = 1,
15157 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15158 .adc_nids = alc861_adc_nids,
15159 .input_mux = &alc861_capture_source,
15160 },
a53d1aec
TD
15161 [ALC861_TOSHIBA] = {
15162 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15163 .init_verbs = { alc861_base_init_verbs,
15164 alc861_toshiba_init_verbs },
a53d1aec
TD
15165 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15166 .dac_nids = alc861_dac_nids,
15167 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15168 .channel_mode = alc883_3ST_2ch_modes,
15169 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15170 .adc_nids = alc861_adc_nids,
15171 .input_mux = &alc861_capture_source,
15172 .unsol_event = alc861_toshiba_unsol_event,
15173 .init_hook = alc861_toshiba_automute,
15174 },
7cdbff94
MD
15175 [ALC861_ASUS] = {
15176 .mixers = { alc861_asus_mixer },
15177 .init_verbs = { alc861_asus_init_verbs },
15178 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15179 .dac_nids = alc861_dac_nids,
15180 .dig_out_nid = ALC861_DIGOUT_NID,
15181 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15182 .channel_mode = alc861_asus_modes,
15183 .need_dac_fix = 1,
15184 .hp_nid = 0x06,
15185 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15186 .adc_nids = alc861_adc_nids,
15187 .input_mux = &alc861_capture_source,
15188 },
56bb0cab
TI
15189 [ALC861_ASUS_LAPTOP] = {
15190 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15191 .init_verbs = { alc861_asus_init_verbs,
15192 alc861_asus_laptop_init_verbs },
15193 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15194 .dac_nids = alc861_dac_nids,
15195 .dig_out_nid = ALC861_DIGOUT_NID,
15196 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15197 .channel_mode = alc883_3ST_2ch_modes,
15198 .need_dac_fix = 1,
15199 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15200 .adc_nids = alc861_adc_nids,
15201 .input_mux = &alc861_capture_source,
15202 },
15203};
df694daa 15204
cfc9b06f
TI
15205/* Pin config fixes */
15206enum {
15207 PINFIX_FSC_AMILO_PI1505,
15208};
15209
15210static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15211 { 0x0b, 0x0221101f }, /* HP */
15212 { 0x0f, 0x90170310 }, /* speaker */
15213 { }
15214};
15215
15216static const struct alc_fixup alc861_fixups[] = {
15217 [PINFIX_FSC_AMILO_PI1505] = {
15218 .pins = alc861_fsc_amilo_pi1505_pinfix
15219 },
15220};
15221
15222static struct snd_pci_quirk alc861_fixup_tbl[] = {
15223 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15224 {}
15225};
df694daa
KY
15226
15227static int patch_alc861(struct hda_codec *codec)
15228{
15229 struct alc_spec *spec;
15230 int board_config;
15231 int err;
15232
dc041e0b 15233 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15234 if (spec == NULL)
15235 return -ENOMEM;
15236
f12ab1e0 15237 codec->spec = spec;
df694daa 15238
f5fcc13c
TI
15239 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15240 alc861_models,
15241 alc861_cfg_tbl);
9c7f852e 15242
f5fcc13c 15243 if (board_config < 0) {
9a11f1aa
TI
15244 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15245 codec->chip_name);
df694daa
KY
15246 board_config = ALC861_AUTO;
15247 }
15248
cfc9b06f
TI
15249 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
15250
df694daa
KY
15251 if (board_config == ALC861_AUTO) {
15252 /* automatic parse from the BIOS config */
15253 err = alc861_parse_auto_config(codec);
15254 if (err < 0) {
15255 alc_free(codec);
15256 return err;
f12ab1e0 15257 } else if (!err) {
9c7f852e
TI
15258 printk(KERN_INFO
15259 "hda_codec: Cannot set up configuration "
15260 "from BIOS. Using base mode...\n");
df694daa
KY
15261 board_config = ALC861_3ST_DIG;
15262 }
15263 }
15264
680cd536
KK
15265 err = snd_hda_attach_beep_device(codec, 0x23);
15266 if (err < 0) {
15267 alc_free(codec);
15268 return err;
15269 }
15270
df694daa 15271 if (board_config != ALC861_AUTO)
e9c364c0 15272 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15273
df694daa
KY
15274 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15275 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15276
df694daa
KY
15277 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15278 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15279
c7a8eb10
TI
15280 if (!spec->cap_mixer)
15281 set_capture_mixer(codec);
45bdd1c1
TI
15282 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15283
2134ea4f
TI
15284 spec->vmaster_nid = 0x03;
15285
df694daa 15286 codec->patch_ops = alc_patch_ops;
c97259df 15287 if (board_config == ALC861_AUTO) {
ae6b813a 15288 spec->init_hook = alc861_auto_init;
c97259df
DC
15289#ifdef CONFIG_SND_HDA_POWER_SAVE
15290 spec->power_hook = alc_power_eapd;
15291#endif
15292 }
cb53c626
TI
15293#ifdef CONFIG_SND_HDA_POWER_SAVE
15294 if (!spec->loopback.amplist)
15295 spec->loopback.amplist = alc861_loopbacks;
15296#endif
ea1fb29a 15297
1da177e4
LT
15298 return 0;
15299}
15300
f32610ed
JS
15301/*
15302 * ALC861-VD support
15303 *
15304 * Based on ALC882
15305 *
15306 * In addition, an independent DAC
15307 */
15308#define ALC861VD_DIGOUT_NID 0x06
15309
15310static hda_nid_t alc861vd_dac_nids[4] = {
15311 /* front, surr, clfe, side surr */
15312 0x02, 0x03, 0x04, 0x05
15313};
15314
15315/* dac_nids for ALC660vd are in a different order - according to
15316 * Realtek's driver.
def319f9 15317 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15318 * of ALC660vd codecs, but for now there is only 3stack mixer
15319 * - and it is the same as in 861vd.
15320 * adc_nids in ALC660vd are (is) the same as in 861vd
15321 */
15322static hda_nid_t alc660vd_dac_nids[3] = {
15323 /* front, rear, clfe, rear_surr */
15324 0x02, 0x04, 0x03
15325};
15326
15327static hda_nid_t alc861vd_adc_nids[1] = {
15328 /* ADC0 */
15329 0x09,
15330};
15331
e1406348
TI
15332static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15333
f32610ed
JS
15334/* input MUX */
15335/* FIXME: should be a matrix-type input source selection */
15336static struct hda_input_mux alc861vd_capture_source = {
15337 .num_items = 4,
15338 .items = {
15339 { "Mic", 0x0 },
15340 { "Front Mic", 0x1 },
15341 { "Line", 0x2 },
15342 { "CD", 0x4 },
15343 },
15344};
15345
272a527c 15346static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15347 .num_items = 2,
272a527c 15348 .items = {
b419f346
TD
15349 { "Ext Mic", 0x0 },
15350 { "Int Mic", 0x1 },
272a527c
KY
15351 },
15352};
15353
d1a991a6
KY
15354static struct hda_input_mux alc861vd_hp_capture_source = {
15355 .num_items = 2,
15356 .items = {
15357 { "Front Mic", 0x0 },
15358 { "ATAPI Mic", 0x1 },
15359 },
15360};
15361
f32610ed
JS
15362/*
15363 * 2ch mode
15364 */
15365static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15366 { 2, NULL }
15367};
15368
15369/*
15370 * 6ch mode
15371 */
15372static struct hda_verb alc861vd_6stack_ch6_init[] = {
15373 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15374 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15375 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15376 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15377 { } /* end */
15378};
15379
15380/*
15381 * 8ch mode
15382 */
15383static struct hda_verb alc861vd_6stack_ch8_init[] = {
15384 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15385 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15386 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15387 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15388 { } /* end */
15389};
15390
15391static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15392 { 6, alc861vd_6stack_ch6_init },
15393 { 8, alc861vd_6stack_ch8_init },
15394};
15395
15396static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15397 {
15398 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15399 .name = "Channel Mode",
15400 .info = alc_ch_mode_info,
15401 .get = alc_ch_mode_get,
15402 .put = alc_ch_mode_put,
15403 },
15404 { } /* end */
15405};
15406
f32610ed
JS
15407/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15408 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15409 */
15410static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15411 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15412 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15413
15414 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15415 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15416
15417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15418 HDA_OUTPUT),
15419 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15420 HDA_OUTPUT),
15421 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15422 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15423
15424 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15425 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15426
15427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15428
15429 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15432
15433 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15436
15437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15439
15440 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15441 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15442
f32610ed
JS
15443 { } /* end */
15444};
15445
15446static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15447 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15448 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15449
15450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15451
15452 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15455
15456 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15459
15460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15462
15463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15465
f32610ed
JS
15466 { } /* end */
15467};
15468
bdd148a3
KY
15469static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15470 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15471 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15472 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15473
15474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15475
15476 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15479
15480 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15481 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15483
15484 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15485 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15486
15487 { } /* end */
15488};
15489
b419f346
TD
15490/* Pin assignment: Speaker=0x14, HP = 0x15,
15491 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
15492 */
15493static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
15494 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15495 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
15496 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15497 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
15498 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
15499 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15500 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15501 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
15502 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15503 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
15504 { } /* end */
15505};
15506
d1a991a6
KY
15507/* Pin assignment: Speaker=0x14, Line-out = 0x15,
15508 * Front Mic=0x18, ATAPI Mic = 0x19,
15509 */
15510static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
15511 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15512 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15513 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15514 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15516 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15517 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15518 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 15519
d1a991a6
KY
15520 { } /* end */
15521};
15522
f32610ed
JS
15523/*
15524 * generic initialization of ADC, input mixers and output mixers
15525 */
15526static struct hda_verb alc861vd_volume_init_verbs[] = {
15527 /*
15528 * Unmute ADC0 and set the default input to mic-in
15529 */
15530 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15532
15533 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
15534 * the analog-loopback mixer widget
15535 */
15536 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15537 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15538 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
15542
15543 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
15544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15545 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15546 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 15547 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
15548
15549 /*
15550 * Set up output mixers (0x02 - 0x05)
15551 */
15552 /* set vol=0 to output mixers */
15553 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15554 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15555 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15556 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15557
15558 /* set up input amps for analog loopback */
15559 /* Amp Indices: DAC = 0, mixer = 1 */
15560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15564 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15566 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15567 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15568
15569 { }
15570};
15571
15572/*
15573 * 3-stack pin configuration:
15574 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15575 */
15576static struct hda_verb alc861vd_3stack_init_verbs[] = {
15577 /*
15578 * Set pin mode and muting
15579 */
15580 /* set front pin widgets 0x14 for output */
15581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15584
15585 /* Mic (rear) pin: input vref at 80% */
15586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15588 /* Front Mic pin: input vref at 80% */
15589 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15590 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15591 /* Line In pin: input */
15592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15593 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15594 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15595 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15596 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15597 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15598 /* CD pin widget for input */
15599 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15600
15601 { }
15602};
15603
15604/*
15605 * 6-stack pin configuration:
15606 */
15607static struct hda_verb alc861vd_6stack_init_verbs[] = {
15608 /*
15609 * Set pin mode and muting
15610 */
15611 /* set front pin widgets 0x14 for output */
15612 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15613 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15615
15616 /* Rear Pin: output 1 (0x0d) */
15617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15618 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15619 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15620 /* CLFE Pin: output 2 (0x0e) */
15621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15622 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15623 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15624 /* Side Pin: output 3 (0x0f) */
15625 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15626 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15628
15629 /* Mic (rear) pin: input vref at 80% */
15630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15632 /* Front Mic pin: input vref at 80% */
15633 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15635 /* Line In pin: input */
15636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15638 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15639 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15640 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15641 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15642 /* CD pin widget for input */
15643 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15644
15645 { }
15646};
15647
bdd148a3
KY
15648static struct hda_verb alc861vd_eapd_verbs[] = {
15649 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15650 { }
15651};
15652
f9423e7a
KY
15653static struct hda_verb alc660vd_eapd_verbs[] = {
15654 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15655 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15656 { }
15657};
15658
bdd148a3
KY
15659static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15662 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15663 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 15664 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
15665 {}
15666};
15667
bdd148a3
KY
15668static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15669{
15670 unsigned int present;
15671 unsigned char bits;
15672
864f92be 15673 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 15674 bits = present ? HDA_AMP_MUTE : 0;
864f92be 15675
47fd830a
TI
15676 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15677 HDA_AMP_MUTE, bits);
bdd148a3
KY
15678}
15679
4f5d1706 15680static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 15681{
a9fd4f3f 15682 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
15683 spec->autocfg.hp_pins[0] = 0x1b;
15684 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
15685}
15686
15687static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15688{
a9fd4f3f 15689 alc_automute_amp(codec);
bdd148a3
KY
15690 alc861vd_lenovo_mic_automute(codec);
15691}
15692
15693static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15694 unsigned int res)
15695{
15696 switch (res >> 26) {
bdd148a3
KY
15697 case ALC880_MIC_EVENT:
15698 alc861vd_lenovo_mic_automute(codec);
15699 break;
a9fd4f3f
TI
15700 default:
15701 alc_automute_amp_unsol_event(codec, res);
15702 break;
bdd148a3
KY
15703 }
15704}
15705
272a527c
KY
15706static struct hda_verb alc861vd_dallas_verbs[] = {
15707 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15708 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15709 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15710 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15711
15712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15714 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15715 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15718 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 15720
272a527c
KY
15721 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15722 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15725 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15726 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15727 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15728 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15729
15730 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15731 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15733 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15734 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15735 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15736 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15737 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15738
15739 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15740 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15741 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15742 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15743
15744 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 15745 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
15746 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15747
15748 { } /* end */
15749};
15750
15751/* toggle speaker-output according to the hp-jack state */
4f5d1706 15752static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 15753{
a9fd4f3f 15754 struct alc_spec *spec = codec->spec;
272a527c 15755
a9fd4f3f
TI
15756 spec->autocfg.hp_pins[0] = 0x15;
15757 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
15758}
15759
cb53c626
TI
15760#ifdef CONFIG_SND_HDA_POWER_SAVE
15761#define alc861vd_loopbacks alc880_loopbacks
15762#endif
15763
def319f9 15764/* pcm configuration: identical with ALC880 */
f32610ed
JS
15765#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15766#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15767#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15768#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15769
15770/*
15771 * configuration and preset
15772 */
15773static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15774 [ALC660VD_3ST] = "3stack-660",
983f8ae4 15775 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 15776 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
15777 [ALC861VD_3ST] = "3stack",
15778 [ALC861VD_3ST_DIG] = "3stack-digout",
15779 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 15780 [ALC861VD_LENOVO] = "lenovo",
272a527c 15781 [ALC861VD_DALLAS] = "dallas",
983f8ae4 15782 [ALC861VD_HP] = "hp",
f32610ed
JS
15783 [ALC861VD_AUTO] = "auto",
15784};
15785
15786static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
15787 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15788 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 15789 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 15790 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 15791 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 15792 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 15793 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 15794 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 15795 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 15796 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 15797 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 15798 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 15799 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 15800 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 15801 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
15802 {}
15803};
15804
15805static struct alc_config_preset alc861vd_presets[] = {
15806 [ALC660VD_3ST] = {
15807 .mixers = { alc861vd_3st_mixer },
15808 .init_verbs = { alc861vd_volume_init_verbs,
15809 alc861vd_3stack_init_verbs },
15810 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15811 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
15812 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15813 .channel_mode = alc861vd_3stack_2ch_modes,
15814 .input_mux = &alc861vd_capture_source,
15815 },
6963f84c
MC
15816 [ALC660VD_3ST_DIG] = {
15817 .mixers = { alc861vd_3st_mixer },
15818 .init_verbs = { alc861vd_volume_init_verbs,
15819 alc861vd_3stack_init_verbs },
15820 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15821 .dac_nids = alc660vd_dac_nids,
15822 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
15823 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15824 .channel_mode = alc861vd_3stack_2ch_modes,
15825 .input_mux = &alc861vd_capture_source,
15826 },
f32610ed
JS
15827 [ALC861VD_3ST] = {
15828 .mixers = { alc861vd_3st_mixer },
15829 .init_verbs = { alc861vd_volume_init_verbs,
15830 alc861vd_3stack_init_verbs },
15831 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15832 .dac_nids = alc861vd_dac_nids,
15833 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15834 .channel_mode = alc861vd_3stack_2ch_modes,
15835 .input_mux = &alc861vd_capture_source,
15836 },
15837 [ALC861VD_3ST_DIG] = {
15838 .mixers = { alc861vd_3st_mixer },
15839 .init_verbs = { alc861vd_volume_init_verbs,
15840 alc861vd_3stack_init_verbs },
15841 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15842 .dac_nids = alc861vd_dac_nids,
15843 .dig_out_nid = ALC861VD_DIGOUT_NID,
15844 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15845 .channel_mode = alc861vd_3stack_2ch_modes,
15846 .input_mux = &alc861vd_capture_source,
15847 },
15848 [ALC861VD_6ST_DIG] = {
15849 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15850 .init_verbs = { alc861vd_volume_init_verbs,
15851 alc861vd_6stack_init_verbs },
15852 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15853 .dac_nids = alc861vd_dac_nids,
15854 .dig_out_nid = ALC861VD_DIGOUT_NID,
15855 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15856 .channel_mode = alc861vd_6stack_modes,
15857 .input_mux = &alc861vd_capture_source,
15858 },
bdd148a3
KY
15859 [ALC861VD_LENOVO] = {
15860 .mixers = { alc861vd_lenovo_mixer },
15861 .init_verbs = { alc861vd_volume_init_verbs,
15862 alc861vd_3stack_init_verbs,
15863 alc861vd_eapd_verbs,
15864 alc861vd_lenovo_unsol_verbs },
15865 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15866 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
15867 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15868 .channel_mode = alc861vd_3stack_2ch_modes,
15869 .input_mux = &alc861vd_capture_source,
15870 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 15871 .setup = alc861vd_lenovo_setup,
a9fd4f3f 15872 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 15873 },
272a527c
KY
15874 [ALC861VD_DALLAS] = {
15875 .mixers = { alc861vd_dallas_mixer },
15876 .init_verbs = { alc861vd_dallas_verbs },
15877 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15878 .dac_nids = alc861vd_dac_nids,
272a527c
KY
15879 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15880 .channel_mode = alc861vd_3stack_2ch_modes,
15881 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 15882 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
15883 .setup = alc861vd_dallas_setup,
15884 .init_hook = alc_automute_amp,
d1a991a6
KY
15885 },
15886 [ALC861VD_HP] = {
15887 .mixers = { alc861vd_hp_mixer },
15888 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15889 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15890 .dac_nids = alc861vd_dac_nids,
d1a991a6 15891 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
15892 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15893 .channel_mode = alc861vd_3stack_2ch_modes,
15894 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 15895 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
15896 .setup = alc861vd_dallas_setup,
15897 .init_hook = alc_automute_amp,
ea1fb29a 15898 },
13c94744
TI
15899 [ALC660VD_ASUS_V1S] = {
15900 .mixers = { alc861vd_lenovo_mixer },
15901 .init_verbs = { alc861vd_volume_init_verbs,
15902 alc861vd_3stack_init_verbs,
15903 alc861vd_eapd_verbs,
15904 alc861vd_lenovo_unsol_verbs },
15905 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15906 .dac_nids = alc660vd_dac_nids,
15907 .dig_out_nid = ALC861VD_DIGOUT_NID,
15908 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15909 .channel_mode = alc861vd_3stack_2ch_modes,
15910 .input_mux = &alc861vd_capture_source,
15911 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 15912 .setup = alc861vd_lenovo_setup,
a9fd4f3f 15913 .init_hook = alc861vd_lenovo_init_hook,
13c94744 15914 },
f32610ed
JS
15915};
15916
15917/*
15918 * BIOS auto configuration
15919 */
05f5f477
TI
15920static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15921 const struct auto_pin_cfg *cfg)
15922{
6227cdce 15923 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
15924}
15925
15926
f32610ed
JS
15927static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15928 hda_nid_t nid, int pin_type, int dac_idx)
15929{
f6c7e546 15930 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
15931}
15932
15933static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15934{
15935 struct alc_spec *spec = codec->spec;
15936 int i;
15937
15938 for (i = 0; i <= HDA_SIDE; i++) {
15939 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15940 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
15941 if (nid)
15942 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 15943 pin_type, i);
f32610ed
JS
15944 }
15945}
15946
15947
15948static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15949{
15950 struct alc_spec *spec = codec->spec;
15951 hda_nid_t pin;
15952
15953 pin = spec->autocfg.hp_pins[0];
def319f9 15954 if (pin) /* connect to front and use dac 0 */
f32610ed 15955 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
15956 pin = spec->autocfg.speaker_pins[0];
15957 if (pin)
15958 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
15959}
15960
f32610ed
JS
15961#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15962
15963static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15964{
15965 struct alc_spec *spec = codec->spec;
15966 int i;
15967
15968 for (i = 0; i < AUTO_PIN_LAST; i++) {
15969 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 15970 if (alc_is_input_pin(codec, nid)) {
23f0c048 15971 alc_set_input_pin(codec, nid, i);
e82c025b
TI
15972 if (nid != ALC861VD_PIN_CD_NID &&
15973 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
15974 snd_hda_codec_write(codec, nid, 0,
15975 AC_VERB_SET_AMP_GAIN_MUTE,
15976 AMP_OUT_MUTE);
15977 }
15978 }
15979}
15980
f511b01c
TI
15981#define alc861vd_auto_init_input_src alc882_auto_init_input_src
15982
f32610ed
JS
15983#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15984#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15985
15986/* add playback controls from the parsed DAC table */
15987/* Based on ALC880 version. But ALC861VD has separate,
15988 * different NIDs for mute/unmute switch and volume control */
15989static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15990 const struct auto_pin_cfg *cfg)
15991{
f32610ed
JS
15992 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15993 hda_nid_t nid_v, nid_s;
15994 int i, err;
15995
15996 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 15997 if (!spec->multiout.dac_nids[i])
f32610ed
JS
15998 continue;
15999 nid_v = alc861vd_idx_to_mixer_vol(
16000 alc880_dac_to_idx(
16001 spec->multiout.dac_nids[i]));
16002 nid_s = alc861vd_idx_to_mixer_switch(
16003 alc880_dac_to_idx(
16004 spec->multiout.dac_nids[i]));
16005
16006 if (i == 2) {
16007 /* Center/LFE */
0afe5f89
TI
16008 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16009 "Center",
f12ab1e0
TI
16010 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16011 HDA_OUTPUT));
16012 if (err < 0)
f32610ed 16013 return err;
0afe5f89
TI
16014 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16015 "LFE",
f12ab1e0
TI
16016 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16017 HDA_OUTPUT));
16018 if (err < 0)
f32610ed 16019 return err;
0afe5f89
TI
16020 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16021 "Center",
f12ab1e0
TI
16022 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16023 HDA_INPUT));
16024 if (err < 0)
f32610ed 16025 return err;
0afe5f89
TI
16026 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16027 "LFE",
f12ab1e0
TI
16028 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16029 HDA_INPUT));
16030 if (err < 0)
f32610ed
JS
16031 return err;
16032 } else {
a4fcd491
TI
16033 const char *pfx;
16034 if (cfg->line_outs == 1 &&
16035 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16036 if (!cfg->hp_pins)
16037 pfx = "Speaker";
16038 else
16039 pfx = "PCM";
16040 } else
16041 pfx = chname[i];
0afe5f89 16042 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16043 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16044 HDA_OUTPUT));
16045 if (err < 0)
f32610ed 16046 return err;
a4fcd491
TI
16047 if (cfg->line_outs == 1 &&
16048 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16049 pfx = "Speaker";
0afe5f89 16050 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16051 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16052 HDA_INPUT));
16053 if (err < 0)
f32610ed
JS
16054 return err;
16055 }
16056 }
16057 return 0;
16058}
16059
16060/* add playback controls for speaker and HP outputs */
16061/* Based on ALC880 version. But ALC861VD has separate,
16062 * different NIDs for mute/unmute switch and volume control */
16063static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16064 hda_nid_t pin, const char *pfx)
16065{
16066 hda_nid_t nid_v, nid_s;
16067 int err;
f32610ed 16068
f12ab1e0 16069 if (!pin)
f32610ed
JS
16070 return 0;
16071
16072 if (alc880_is_fixed_pin(pin)) {
16073 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16074 /* specify the DAC as the extra output */
f12ab1e0 16075 if (!spec->multiout.hp_nid)
f32610ed
JS
16076 spec->multiout.hp_nid = nid_v;
16077 else
16078 spec->multiout.extra_out_nid[0] = nid_v;
16079 /* control HP volume/switch on the output mixer amp */
16080 nid_v = alc861vd_idx_to_mixer_vol(
16081 alc880_fixed_pin_idx(pin));
16082 nid_s = alc861vd_idx_to_mixer_switch(
16083 alc880_fixed_pin_idx(pin));
16084
0afe5f89 16085 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16086 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16087 if (err < 0)
f32610ed 16088 return err;
0afe5f89 16089 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16090 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16091 if (err < 0)
f32610ed
JS
16092 return err;
16093 } else if (alc880_is_multi_pin(pin)) {
16094 /* set manual connection */
16095 /* we have only a switch on HP-out PIN */
0afe5f89 16096 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16097 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16098 if (err < 0)
f32610ed
JS
16099 return err;
16100 }
16101 return 0;
16102}
16103
16104/* parse the BIOS configuration and set up the alc_spec
16105 * return 1 if successful, 0 if the proper config is not found,
16106 * or a negative error code
16107 * Based on ALC880 version - had to change it to override
16108 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16109static int alc861vd_parse_auto_config(struct hda_codec *codec)
16110{
16111 struct alc_spec *spec = codec->spec;
16112 int err;
16113 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16114
f12ab1e0
TI
16115 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16116 alc861vd_ignore);
16117 if (err < 0)
f32610ed 16118 return err;
f12ab1e0 16119 if (!spec->autocfg.line_outs)
f32610ed
JS
16120 return 0; /* can't find valid BIOS pin config */
16121
f12ab1e0
TI
16122 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16123 if (err < 0)
16124 return err;
16125 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16126 if (err < 0)
16127 return err;
16128 err = alc861vd_auto_create_extra_out(spec,
16129 spec->autocfg.speaker_pins[0],
16130 "Speaker");
16131 if (err < 0)
16132 return err;
16133 err = alc861vd_auto_create_extra_out(spec,
16134 spec->autocfg.hp_pins[0],
16135 "Headphone");
16136 if (err < 0)
16137 return err;
05f5f477 16138 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16139 if (err < 0)
f32610ed
JS
16140 return err;
16141
16142 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16143
0852d7a6 16144 if (spec->autocfg.dig_outs)
f32610ed
JS
16145 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16146
603c4019 16147 if (spec->kctls.list)
d88897ea 16148 add_mixer(spec, spec->kctls.list);
f32610ed 16149
d88897ea 16150 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16151
16152 spec->num_mux_defs = 1;
61b9b9b1 16153 spec->input_mux = &spec->private_imux[0];
f32610ed 16154
776e184e
TI
16155 err = alc_auto_add_mic_boost(codec);
16156 if (err < 0)
16157 return err;
16158
6227cdce 16159 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16160
f32610ed
JS
16161 return 1;
16162}
16163
16164/* additional initialization for auto-configuration model */
16165static void alc861vd_auto_init(struct hda_codec *codec)
16166{
f6c7e546 16167 struct alc_spec *spec = codec->spec;
f32610ed
JS
16168 alc861vd_auto_init_multi_out(codec);
16169 alc861vd_auto_init_hp_out(codec);
16170 alc861vd_auto_init_analog_input(codec);
f511b01c 16171 alc861vd_auto_init_input_src(codec);
f6c7e546 16172 if (spec->unsol_event)
7fb0d78f 16173 alc_inithook(codec);
f32610ed
JS
16174}
16175
f8f25ba3
TI
16176enum {
16177 ALC660VD_FIX_ASUS_GPIO1
16178};
16179
16180/* reset GPIO1 */
16181static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16182 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16183 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16184 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16185 { }
16186};
16187
16188static const struct alc_fixup alc861vd_fixups[] = {
16189 [ALC660VD_FIX_ASUS_GPIO1] = {
16190 .verbs = alc660vd_fix_asus_gpio1_verbs,
16191 },
16192};
16193
16194static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16195 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16196 {}
16197};
16198
f32610ed
JS
16199static int patch_alc861vd(struct hda_codec *codec)
16200{
16201 struct alc_spec *spec;
16202 int err, board_config;
16203
16204 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16205 if (spec == NULL)
16206 return -ENOMEM;
16207
16208 codec->spec = spec;
16209
16210 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16211 alc861vd_models,
16212 alc861vd_cfg_tbl);
16213
16214 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16215 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16216 codec->chip_name);
f32610ed
JS
16217 board_config = ALC861VD_AUTO;
16218 }
16219
f8f25ba3
TI
16220 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
16221
f32610ed
JS
16222 if (board_config == ALC861VD_AUTO) {
16223 /* automatic parse from the BIOS config */
16224 err = alc861vd_parse_auto_config(codec);
16225 if (err < 0) {
16226 alc_free(codec);
16227 return err;
f12ab1e0 16228 } else if (!err) {
f32610ed
JS
16229 printk(KERN_INFO
16230 "hda_codec: Cannot set up configuration "
16231 "from BIOS. Using base mode...\n");
16232 board_config = ALC861VD_3ST;
16233 }
16234 }
16235
680cd536
KK
16236 err = snd_hda_attach_beep_device(codec, 0x23);
16237 if (err < 0) {
16238 alc_free(codec);
16239 return err;
16240 }
16241
f32610ed 16242 if (board_config != ALC861VD_AUTO)
e9c364c0 16243 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16244
2f893286 16245 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16246 /* always turn on EAPD */
d88897ea 16247 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16248 }
16249
f32610ed
JS
16250 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16251 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16252
f32610ed
JS
16253 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16254 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16255
dd704698
TI
16256 if (!spec->adc_nids) {
16257 spec->adc_nids = alc861vd_adc_nids;
16258 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16259 }
16260 if (!spec->capsrc_nids)
16261 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16262
b59bdf3b 16263 set_capture_mixer(codec);
45bdd1c1 16264 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16265
2134ea4f
TI
16266 spec->vmaster_nid = 0x02;
16267
f32610ed
JS
16268 codec->patch_ops = alc_patch_ops;
16269
16270 if (board_config == ALC861VD_AUTO)
16271 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16272#ifdef CONFIG_SND_HDA_POWER_SAVE
16273 if (!spec->loopback.amplist)
16274 spec->loopback.amplist = alc861vd_loopbacks;
16275#endif
f32610ed
JS
16276
16277 return 0;
16278}
16279
bc9f98a9
KY
16280/*
16281 * ALC662 support
16282 *
16283 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16284 * configuration. Each pin widget can choose any input DACs and a mixer.
16285 * Each ADC is connected from a mixer of all inputs. This makes possible
16286 * 6-channel independent captures.
16287 *
16288 * In addition, an independent DAC for the multi-playback (not used in this
16289 * driver yet).
16290 */
16291#define ALC662_DIGOUT_NID 0x06
16292#define ALC662_DIGIN_NID 0x0a
16293
16294static hda_nid_t alc662_dac_nids[4] = {
16295 /* front, rear, clfe, rear_surr */
16296 0x02, 0x03, 0x04
16297};
16298
622e84cd
KY
16299static hda_nid_t alc272_dac_nids[2] = {
16300 0x02, 0x03
16301};
16302
b59bdf3b 16303static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16304 /* ADC1-2 */
b59bdf3b 16305 0x09, 0x08
bc9f98a9 16306};
e1406348 16307
622e84cd
KY
16308static hda_nid_t alc272_adc_nids[1] = {
16309 /* ADC1-2 */
16310 0x08,
16311};
16312
b59bdf3b 16313static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16314static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16315
e1406348 16316
bc9f98a9
KY
16317/* input MUX */
16318/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16319static struct hda_input_mux alc662_capture_source = {
16320 .num_items = 4,
16321 .items = {
16322 { "Mic", 0x0 },
16323 { "Front Mic", 0x1 },
16324 { "Line", 0x2 },
16325 { "CD", 0x4 },
16326 },
16327};
16328
16329static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16330 .num_items = 2,
16331 .items = {
16332 { "Mic", 0x1 },
16333 { "Line", 0x2 },
16334 },
16335};
291702f0 16336
6dda9f4a
KY
16337static struct hda_input_mux alc663_capture_source = {
16338 .num_items = 3,
16339 .items = {
16340 { "Mic", 0x0 },
16341 { "Front Mic", 0x1 },
16342 { "Line", 0x2 },
16343 },
16344};
16345
4f5d1706 16346#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16347static struct hda_input_mux alc272_nc10_capture_source = {
16348 .num_items = 16,
16349 .items = {
16350 { "Autoselect Mic", 0x0 },
16351 { "Internal Mic", 0x1 },
16352 { "In-0x02", 0x2 },
16353 { "In-0x03", 0x3 },
16354 { "In-0x04", 0x4 },
16355 { "In-0x05", 0x5 },
16356 { "In-0x06", 0x6 },
16357 { "In-0x07", 0x7 },
16358 { "In-0x08", 0x8 },
16359 { "In-0x09", 0x9 },
16360 { "In-0x0a", 0x0a },
16361 { "In-0x0b", 0x0b },
16362 { "In-0x0c", 0x0c },
16363 { "In-0x0d", 0x0d },
16364 { "In-0x0e", 0x0e },
16365 { "In-0x0f", 0x0f },
16366 },
16367};
16368#endif
16369
bc9f98a9
KY
16370/*
16371 * 2ch mode
16372 */
16373static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16374 { 2, NULL }
16375};
16376
16377/*
16378 * 2ch mode
16379 */
16380static struct hda_verb alc662_3ST_ch2_init[] = {
16381 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16382 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16383 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16384 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16385 { } /* end */
16386};
16387
16388/*
16389 * 6ch mode
16390 */
16391static struct hda_verb alc662_3ST_ch6_init[] = {
16392 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16393 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16394 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16395 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16396 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16397 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16398 { } /* end */
16399};
16400
16401static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16402 { 2, alc662_3ST_ch2_init },
16403 { 6, alc662_3ST_ch6_init },
16404};
16405
16406/*
16407 * 2ch mode
16408 */
16409static struct hda_verb alc662_sixstack_ch6_init[] = {
16410 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16411 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16412 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16413 { } /* end */
16414};
16415
16416/*
16417 * 6ch mode
16418 */
16419static struct hda_verb alc662_sixstack_ch8_init[] = {
16420 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16421 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16422 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16423 { } /* end */
16424};
16425
16426static struct hda_channel_mode alc662_5stack_modes[2] = {
16427 { 2, alc662_sixstack_ch6_init },
16428 { 6, alc662_sixstack_ch8_init },
16429};
16430
16431/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16432 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16433 */
16434
16435static struct snd_kcontrol_new alc662_base_mixer[] = {
16436 /* output mixer control */
16437 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16438 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16439 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16440 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16441 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16442 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16443 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16444 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16446
16447 /*Input mixer control */
16448 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16449 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16450 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16451 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16452 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16453 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16456 { } /* end */
16457};
16458
16459static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16460 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16461 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
16462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16469 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16470 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16471 { } /* end */
16472};
16473
16474static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16475 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16476 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16477 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 16478 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16479 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16480 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16481 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16482 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16484 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16485 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16486 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16487 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16490 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16491 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16492 { } /* end */
16493};
16494
16495static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16496 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16497 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
16498 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16499 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
16500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16501 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16502 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16505 { } /* end */
16506};
16507
291702f0 16508static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
16509 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16510 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
16511
16512 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
16513 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16514 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16515
16516 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16517 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16518 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16519 { } /* end */
16520};
16521
8c427226 16522static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
16523 ALC262_HIPPO_MASTER_SWITCH,
16524 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 16525 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
16526 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16527 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
16528 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
16529 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16530 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16532 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16533 { } /* end */
16534};
16535
f1d4e28b
KY
16536static struct hda_bind_ctls alc663_asus_bind_master_vol = {
16537 .ops = &snd_hda_bind_vol,
16538 .values = {
16539 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16540 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
16541 0
16542 },
16543};
16544
16545static struct hda_bind_ctls alc663_asus_one_bind_switch = {
16546 .ops = &snd_hda_bind_sw,
16547 .values = {
16548 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16549 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16550 0
16551 },
16552};
16553
6dda9f4a 16554static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
16555 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16556 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16557 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16558 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16559 { } /* end */
16560};
16561
16562static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16563 .ops = &snd_hda_bind_sw,
16564 .values = {
16565 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16566 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16567 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16568 0
16569 },
16570};
16571
16572static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16573 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16574 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16577 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16578 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16579
16580 { } /* end */
16581};
16582
16583static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16584 .ops = &snd_hda_bind_sw,
16585 .values = {
16586 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16587 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16588 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16589 0
16590 },
16591};
16592
16593static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16594 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16595 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16596 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16598 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16599 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16600 { } /* end */
16601};
16602
16603static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
16604 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16605 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
16606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16607 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16608 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16609 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16610 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16611 { } /* end */
16612};
16613
16614static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16615 .ops = &snd_hda_bind_vol,
16616 .values = {
16617 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16618 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16619 0
16620 },
16621};
16622
16623static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16624 .ops = &snd_hda_bind_sw,
16625 .values = {
16626 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16627 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16628 0
16629 },
16630};
16631
16632static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16633 HDA_BIND_VOL("Master Playback Volume",
16634 &alc663_asus_two_bind_master_vol),
16635 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
16637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
16640 { } /* end */
16641};
16642
16643static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16644 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16645 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16646 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
16650 { } /* end */
16651};
16652
16653static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16654 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16655 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16656 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16657 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16659
16660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16662 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16663 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16664 { } /* end */
16665};
16666
16667static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16668 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16669 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16670 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16671
16672 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16674 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16675 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16678 { } /* end */
16679};
16680
ebb83eeb
KY
16681static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
16682 .ops = &snd_hda_bind_sw,
16683 .values = {
16684 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16685 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16686 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16687 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16688 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16689 0
16690 },
16691};
16692
16693static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
16694 .ops = &snd_hda_bind_sw,
16695 .values = {
16696 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16697 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16698 0
16699 },
16700};
16701
16702static struct snd_kcontrol_new alc663_mode7_mixer[] = {
16703 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16704 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16705 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16706 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16707 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16708 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16709 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16712 { } /* end */
16713};
16714
16715static struct snd_kcontrol_new alc663_mode8_mixer[] = {
16716 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16717 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16718 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16719 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16720 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16723 { } /* end */
16724};
16725
16726
bc9f98a9
KY
16727static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16728 {
16729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16730 .name = "Channel Mode",
16731 .info = alc_ch_mode_info,
16732 .get = alc_ch_mode_get,
16733 .put = alc_ch_mode_put,
16734 },
16735 { } /* end */
16736};
16737
16738static struct hda_verb alc662_init_verbs[] = {
16739 /* ADC: mute amp left and right */
16740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16741 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 16742
b60dd394
KY
16743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
16749
16750 /* Front Pin: output 0 (0x0c) */
16751 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16752 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16753
16754 /* Rear Pin: output 1 (0x0d) */
16755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16757
16758 /* CLFE Pin: output 2 (0x0e) */
16759 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16760 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16761
16762 /* Mic (rear) pin: input vref at 80% */
16763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16764 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16765 /* Front Mic pin: input vref at 80% */
16766 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16767 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16768 /* Line In pin: input */
16769 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16770 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16771 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16772 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16773 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16774 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16775 /* CD pin widget for input */
16776 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16777
16778 /* FIXME: use matrix-type input source selection */
16779 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16780 /* Input mixer */
16781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 16782 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
16783
16784 /* always trun on EAPD */
16785 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16786 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16787
bc9f98a9
KY
16788 { }
16789};
16790
cec27c89
KY
16791static struct hda_verb alc663_init_verbs[] = {
16792 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16793 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16794 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16795 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16798 { }
16799};
16800
16801static struct hda_verb alc272_init_verbs[] = {
16802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16804 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16805 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16806 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16807 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16809 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16810 { }
16811};
16812
bc9f98a9
KY
16813static struct hda_verb alc662_sue_init_verbs[] = {
16814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16815 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
16816 {}
16817};
16818
16819static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16820 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16821 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16822 {}
bc9f98a9
KY
16823};
16824
8c427226
KY
16825/* Set Unsolicited Event*/
16826static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16828 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16829 {}
16830};
16831
6dda9f4a 16832static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
16833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
16835 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16836 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
16837 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16839 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16840 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16841 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16842 {}
16843};
16844
16845static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16846 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16847 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16848 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16850 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16851 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16852 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16853 {}
16854};
16855
16856static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16857 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16858 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16859 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16860 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16863 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16864 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16865 {}
16866};
6dda9f4a 16867
f1d4e28b
KY
16868static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16869 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16871 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16874 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16875 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16876 {}
16877};
6dda9f4a 16878
f1d4e28b
KY
16879static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16880 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16881 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16882 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16883 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16885 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16886 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16888 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
16889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16890 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
16891 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16892 {}
16893};
16894
16895static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16896 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16897 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16898 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16900 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16901 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16902 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16903 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16904 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16905 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16906 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16907 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
16908 {}
16909};
16910
16911static struct hda_verb alc663_g71v_init_verbs[] = {
16912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16913 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16914 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16915
16916 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16917 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16918 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16919
16920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16921 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16922 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16923 {}
16924};
16925
16926static struct hda_verb alc663_g50v_init_verbs[] = {
16927 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16928 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16929 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16930
16931 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16932 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16933 {}
16934};
16935
f1d4e28b
KY
16936static struct hda_verb alc662_ecs_init_verbs[] = {
16937 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16939 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16940 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16941 {}
16942};
16943
622e84cd
KY
16944static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16945 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16946 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16949 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16950 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16951 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16954 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16955 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16956 {}
16957};
16958
16959static struct hda_verb alc272_dell_init_verbs[] = {
16960 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16961 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16964 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16965 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16966 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16967 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16968 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16970 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16971 {}
16972};
16973
ebb83eeb
KY
16974static struct hda_verb alc663_mode7_init_verbs[] = {
16975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16976 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16977 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16978 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16980 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16981 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
16982 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16983 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16984 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16987 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16988 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16989 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16990 {}
16991};
16992
16993static struct hda_verb alc663_mode8_init_verbs[] = {
16994 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16997 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16998 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16999 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17000 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17002 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17003 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17004 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17007 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17008 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17009 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17010 {}
17011};
17012
f1d4e28b
KY
17013static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17014 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17015 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17016 { } /* end */
17017};
17018
622e84cd
KY
17019static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17020 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17021 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17022 { } /* end */
17023};
17024
bc9f98a9
KY
17025static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17026{
17027 unsigned int present;
f12ab1e0 17028 unsigned char bits;
bc9f98a9 17029
864f92be 17030 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17031 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17032
47fd830a
TI
17033 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17034 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17035}
17036
17037static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17038{
17039 unsigned int present;
f12ab1e0 17040 unsigned char bits;
bc9f98a9 17041
864f92be 17042 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17043 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17044
47fd830a
TI
17045 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17046 HDA_AMP_MUTE, bits);
17047 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17048 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17049}
17050
17051static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17052 unsigned int res)
17053{
17054 if ((res >> 26) == ALC880_HP_EVENT)
17055 alc662_lenovo_101e_all_automute(codec);
17056 if ((res >> 26) == ALC880_FRONT_EVENT)
17057 alc662_lenovo_101e_ispeaker_automute(codec);
17058}
17059
291702f0
KY
17060/* unsolicited event for HP jack sensing */
17061static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17062 unsigned int res)
17063{
291702f0 17064 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17065 alc_mic_automute(codec);
42171c17
TI
17066 else
17067 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17068}
17069
4f5d1706
TI
17070static void alc662_eeepc_setup(struct hda_codec *codec)
17071{
17072 struct alc_spec *spec = codec->spec;
17073
17074 alc262_hippo1_setup(codec);
17075 spec->ext_mic.pin = 0x18;
17076 spec->ext_mic.mux_idx = 0;
17077 spec->int_mic.pin = 0x19;
17078 spec->int_mic.mux_idx = 1;
17079 spec->auto_mic = 1;
17080}
17081
291702f0
KY
17082static void alc662_eeepc_inithook(struct hda_codec *codec)
17083{
4f5d1706
TI
17084 alc262_hippo_automute(codec);
17085 alc_mic_automute(codec);
291702f0
KY
17086}
17087
4f5d1706 17088static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17089{
42171c17
TI
17090 struct alc_spec *spec = codec->spec;
17091
17092 spec->autocfg.hp_pins[0] = 0x14;
17093 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17094}
17095
4f5d1706
TI
17096#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17097
6dda9f4a
KY
17098static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17099{
17100 unsigned int present;
17101 unsigned char bits;
17102
864f92be 17103 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17104 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
17105 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17106 AMP_IN_MUTE(0), bits);
17107 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17108 AMP_IN_MUTE(0), bits);
17109}
17110
17111static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17112{
17113 unsigned int present;
17114 unsigned char bits;
17115
864f92be 17116 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17117 bits = present ? HDA_AMP_MUTE : 0;
17118 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17119 AMP_IN_MUTE(0), bits);
17120 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17121 AMP_IN_MUTE(0), bits);
17122 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17123 AMP_IN_MUTE(0), bits);
17124 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17125 AMP_IN_MUTE(0), bits);
17126}
17127
17128static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17129{
17130 unsigned int present;
17131 unsigned char bits;
17132
864f92be 17133 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17134 bits = present ? HDA_AMP_MUTE : 0;
17135 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17136 AMP_IN_MUTE(0), bits);
17137 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17138 AMP_IN_MUTE(0), bits);
17139 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17140 AMP_IN_MUTE(0), bits);
17141 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17142 AMP_IN_MUTE(0), bits);
17143}
17144
17145static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17146{
17147 unsigned int present;
17148 unsigned char bits;
17149
864f92be 17150 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17151 bits = present ? 0 : PIN_OUT;
17152 snd_hda_codec_write(codec, 0x14, 0,
17153 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17154}
17155
17156static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17157{
17158 unsigned int present1, present2;
17159
864f92be
WF
17160 present1 = snd_hda_jack_detect(codec, 0x21);
17161 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17162
17163 if (present1 || present2) {
17164 snd_hda_codec_write_cache(codec, 0x14, 0,
17165 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17166 } else {
17167 snd_hda_codec_write_cache(codec, 0x14, 0,
17168 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17169 }
17170}
17171
17172static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17173{
17174 unsigned int present1, present2;
17175
864f92be
WF
17176 present1 = snd_hda_jack_detect(codec, 0x1b);
17177 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17178
17179 if (present1 || present2) {
17180 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17181 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
17182 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17183 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
17184 } else {
17185 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17186 AMP_IN_MUTE(0), 0);
17187 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17188 AMP_IN_MUTE(0), 0);
17189 }
6dda9f4a
KY
17190}
17191
ebb83eeb
KY
17192static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17193{
17194 unsigned int present1, present2;
17195
17196 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17197 AC_VERB_GET_PIN_SENSE, 0)
17198 & AC_PINSENSE_PRESENCE;
17199 present2 = snd_hda_codec_read(codec, 0x21, 0,
17200 AC_VERB_GET_PIN_SENSE, 0)
17201 & AC_PINSENSE_PRESENCE;
17202
17203 if (present1 || present2) {
17204 snd_hda_codec_write_cache(codec, 0x14, 0,
17205 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17206 snd_hda_codec_write_cache(codec, 0x17, 0,
17207 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17208 } else {
17209 snd_hda_codec_write_cache(codec, 0x14, 0,
17210 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17211 snd_hda_codec_write_cache(codec, 0x17, 0,
17212 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17213 }
17214}
17215
17216static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17217{
17218 unsigned int present1, present2;
17219
17220 present1 = snd_hda_codec_read(codec, 0x21, 0,
17221 AC_VERB_GET_PIN_SENSE, 0)
17222 & AC_PINSENSE_PRESENCE;
17223 present2 = snd_hda_codec_read(codec, 0x15, 0,
17224 AC_VERB_GET_PIN_SENSE, 0)
17225 & AC_PINSENSE_PRESENCE;
17226
17227 if (present1 || present2) {
17228 snd_hda_codec_write_cache(codec, 0x14, 0,
17229 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17230 snd_hda_codec_write_cache(codec, 0x17, 0,
17231 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17232 } else {
17233 snd_hda_codec_write_cache(codec, 0x14, 0,
17234 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17235 snd_hda_codec_write_cache(codec, 0x17, 0,
17236 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17237 }
17238}
17239
6dda9f4a
KY
17240static void alc663_m51va_unsol_event(struct hda_codec *codec,
17241 unsigned int res)
17242{
17243 switch (res >> 26) {
17244 case ALC880_HP_EVENT:
17245 alc663_m51va_speaker_automute(codec);
17246 break;
17247 case ALC880_MIC_EVENT:
4f5d1706 17248 alc_mic_automute(codec);
6dda9f4a
KY
17249 break;
17250 }
17251}
17252
4f5d1706
TI
17253static void alc663_m51va_setup(struct hda_codec *codec)
17254{
17255 struct alc_spec *spec = codec->spec;
17256 spec->ext_mic.pin = 0x18;
17257 spec->ext_mic.mux_idx = 0;
17258 spec->int_mic.pin = 0x12;
ebb83eeb 17259 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17260 spec->auto_mic = 1;
17261}
17262
6dda9f4a
KY
17263static void alc663_m51va_inithook(struct hda_codec *codec)
17264{
17265 alc663_m51va_speaker_automute(codec);
4f5d1706 17266 alc_mic_automute(codec);
6dda9f4a
KY
17267}
17268
f1d4e28b 17269/* ***************** Mode1 ******************************/
4f5d1706 17270#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17271
17272static void alc663_mode1_setup(struct hda_codec *codec)
17273{
17274 struct alc_spec *spec = codec->spec;
17275 spec->ext_mic.pin = 0x18;
17276 spec->ext_mic.mux_idx = 0;
17277 spec->int_mic.pin = 0x19;
17278 spec->int_mic.mux_idx = 1;
17279 spec->auto_mic = 1;
17280}
17281
4f5d1706 17282#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17283
f1d4e28b
KY
17284/* ***************** Mode2 ******************************/
17285static void alc662_mode2_unsol_event(struct hda_codec *codec,
17286 unsigned int res)
17287{
17288 switch (res >> 26) {
17289 case ALC880_HP_EVENT:
17290 alc662_f5z_speaker_automute(codec);
17291 break;
17292 case ALC880_MIC_EVENT:
4f5d1706 17293 alc_mic_automute(codec);
f1d4e28b
KY
17294 break;
17295 }
17296}
17297
ebb83eeb 17298#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17299
f1d4e28b
KY
17300static void alc662_mode2_inithook(struct hda_codec *codec)
17301{
17302 alc662_f5z_speaker_automute(codec);
4f5d1706 17303 alc_mic_automute(codec);
f1d4e28b
KY
17304}
17305/* ***************** Mode3 ******************************/
17306static void alc663_mode3_unsol_event(struct hda_codec *codec,
17307 unsigned int res)
17308{
17309 switch (res >> 26) {
17310 case ALC880_HP_EVENT:
17311 alc663_two_hp_m1_speaker_automute(codec);
17312 break;
17313 case ALC880_MIC_EVENT:
4f5d1706 17314 alc_mic_automute(codec);
f1d4e28b
KY
17315 break;
17316 }
17317}
17318
ebb83eeb 17319#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17320
f1d4e28b
KY
17321static void alc663_mode3_inithook(struct hda_codec *codec)
17322{
17323 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17324 alc_mic_automute(codec);
f1d4e28b
KY
17325}
17326/* ***************** Mode4 ******************************/
17327static void alc663_mode4_unsol_event(struct hda_codec *codec,
17328 unsigned int res)
17329{
17330 switch (res >> 26) {
17331 case ALC880_HP_EVENT:
17332 alc663_21jd_two_speaker_automute(codec);
17333 break;
17334 case ALC880_MIC_EVENT:
4f5d1706 17335 alc_mic_automute(codec);
f1d4e28b
KY
17336 break;
17337 }
17338}
17339
ebb83eeb 17340#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17341
f1d4e28b
KY
17342static void alc663_mode4_inithook(struct hda_codec *codec)
17343{
17344 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17345 alc_mic_automute(codec);
f1d4e28b
KY
17346}
17347/* ***************** Mode5 ******************************/
17348static void alc663_mode5_unsol_event(struct hda_codec *codec,
17349 unsigned int res)
17350{
17351 switch (res >> 26) {
17352 case ALC880_HP_EVENT:
17353 alc663_15jd_two_speaker_automute(codec);
17354 break;
17355 case ALC880_MIC_EVENT:
4f5d1706 17356 alc_mic_automute(codec);
f1d4e28b
KY
17357 break;
17358 }
17359}
17360
ebb83eeb 17361#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17362
f1d4e28b
KY
17363static void alc663_mode5_inithook(struct hda_codec *codec)
17364{
17365 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17366 alc_mic_automute(codec);
f1d4e28b
KY
17367}
17368/* ***************** Mode6 ******************************/
17369static void alc663_mode6_unsol_event(struct hda_codec *codec,
17370 unsigned int res)
17371{
17372 switch (res >> 26) {
17373 case ALC880_HP_EVENT:
17374 alc663_two_hp_m2_speaker_automute(codec);
17375 break;
17376 case ALC880_MIC_EVENT:
4f5d1706 17377 alc_mic_automute(codec);
f1d4e28b
KY
17378 break;
17379 }
17380}
17381
ebb83eeb 17382#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17383
f1d4e28b
KY
17384static void alc663_mode6_inithook(struct hda_codec *codec)
17385{
17386 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17387 alc_mic_automute(codec);
f1d4e28b
KY
17388}
17389
ebb83eeb
KY
17390/* ***************** Mode7 ******************************/
17391static void alc663_mode7_unsol_event(struct hda_codec *codec,
17392 unsigned int res)
17393{
17394 switch (res >> 26) {
17395 case ALC880_HP_EVENT:
17396 alc663_two_hp_m7_speaker_automute(codec);
17397 break;
17398 case ALC880_MIC_EVENT:
17399 alc_mic_automute(codec);
17400 break;
17401 }
17402}
17403
17404#define alc663_mode7_setup alc663_mode1_setup
17405
17406static void alc663_mode7_inithook(struct hda_codec *codec)
17407{
17408 alc663_two_hp_m7_speaker_automute(codec);
17409 alc_mic_automute(codec);
17410}
17411
17412/* ***************** Mode8 ******************************/
17413static void alc663_mode8_unsol_event(struct hda_codec *codec,
17414 unsigned int res)
17415{
17416 switch (res >> 26) {
17417 case ALC880_HP_EVENT:
17418 alc663_two_hp_m8_speaker_automute(codec);
17419 break;
17420 case ALC880_MIC_EVENT:
17421 alc_mic_automute(codec);
17422 break;
17423 }
17424}
17425
17426#define alc663_mode8_setup alc663_m51va_setup
17427
17428static void alc663_mode8_inithook(struct hda_codec *codec)
17429{
17430 alc663_two_hp_m8_speaker_automute(codec);
17431 alc_mic_automute(codec);
17432}
17433
6dda9f4a
KY
17434static void alc663_g71v_hp_automute(struct hda_codec *codec)
17435{
17436 unsigned int present;
17437 unsigned char bits;
17438
864f92be 17439 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17440 bits = present ? HDA_AMP_MUTE : 0;
17441 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17442 HDA_AMP_MUTE, bits);
17443 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17444 HDA_AMP_MUTE, bits);
17445}
17446
17447static void alc663_g71v_front_automute(struct hda_codec *codec)
17448{
17449 unsigned int present;
17450 unsigned char bits;
17451
864f92be 17452 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17453 bits = present ? HDA_AMP_MUTE : 0;
17454 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17455 HDA_AMP_MUTE, bits);
17456}
17457
17458static void alc663_g71v_unsol_event(struct hda_codec *codec,
17459 unsigned int res)
17460{
17461 switch (res >> 26) {
17462 case ALC880_HP_EVENT:
17463 alc663_g71v_hp_automute(codec);
17464 break;
17465 case ALC880_FRONT_EVENT:
17466 alc663_g71v_front_automute(codec);
17467 break;
17468 case ALC880_MIC_EVENT:
4f5d1706 17469 alc_mic_automute(codec);
6dda9f4a
KY
17470 break;
17471 }
17472}
17473
4f5d1706
TI
17474#define alc663_g71v_setup alc663_m51va_setup
17475
6dda9f4a
KY
17476static void alc663_g71v_inithook(struct hda_codec *codec)
17477{
17478 alc663_g71v_front_automute(codec);
17479 alc663_g71v_hp_automute(codec);
4f5d1706 17480 alc_mic_automute(codec);
6dda9f4a
KY
17481}
17482
17483static void alc663_g50v_unsol_event(struct hda_codec *codec,
17484 unsigned int res)
17485{
17486 switch (res >> 26) {
17487 case ALC880_HP_EVENT:
17488 alc663_m51va_speaker_automute(codec);
17489 break;
17490 case ALC880_MIC_EVENT:
4f5d1706 17491 alc_mic_automute(codec);
6dda9f4a
KY
17492 break;
17493 }
17494}
17495
4f5d1706
TI
17496#define alc663_g50v_setup alc663_m51va_setup
17497
6dda9f4a
KY
17498static void alc663_g50v_inithook(struct hda_codec *codec)
17499{
17500 alc663_m51va_speaker_automute(codec);
4f5d1706 17501 alc_mic_automute(codec);
6dda9f4a
KY
17502}
17503
f1d4e28b
KY
17504static struct snd_kcontrol_new alc662_ecs_mixer[] = {
17505 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 17506 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
17507
17508 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
17509 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17510 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17511
17512 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17513 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17514 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17515 { } /* end */
17516};
17517
9541ba1d
CP
17518static struct snd_kcontrol_new alc272_nc10_mixer[] = {
17519 /* Master Playback automatically created from Speaker and Headphone */
17520 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17521 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17523 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17524
17525 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17526 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17527 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
17528
17529 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17530 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17531 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
17532 { } /* end */
17533};
17534
cb53c626
TI
17535#ifdef CONFIG_SND_HDA_POWER_SAVE
17536#define alc662_loopbacks alc880_loopbacks
17537#endif
17538
bc9f98a9 17539
def319f9 17540/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
17541#define alc662_pcm_analog_playback alc880_pcm_analog_playback
17542#define alc662_pcm_analog_capture alc880_pcm_analog_capture
17543#define alc662_pcm_digital_playback alc880_pcm_digital_playback
17544#define alc662_pcm_digital_capture alc880_pcm_digital_capture
17545
17546/*
17547 * configuration and preset
17548 */
17549static const char *alc662_models[ALC662_MODEL_LAST] = {
17550 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17551 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17552 [ALC662_3ST_6ch] = "3stack-6ch",
17553 [ALC662_5ST_DIG] = "6stack-dig",
17554 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 17555 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 17556 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 17557 [ALC662_ECS] = "ecs",
6dda9f4a
KY
17558 [ALC663_ASUS_M51VA] = "m51va",
17559 [ALC663_ASUS_G71V] = "g71v",
17560 [ALC663_ASUS_H13] = "h13",
17561 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
17562 [ALC663_ASUS_MODE1] = "asus-mode1",
17563 [ALC662_ASUS_MODE2] = "asus-mode2",
17564 [ALC663_ASUS_MODE3] = "asus-mode3",
17565 [ALC663_ASUS_MODE4] = "asus-mode4",
17566 [ALC663_ASUS_MODE5] = "asus-mode5",
17567 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
17568 [ALC663_ASUS_MODE7] = "asus-mode7",
17569 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
17570 [ALC272_DELL] = "dell",
17571 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 17572 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
17573 [ALC662_AUTO] = "auto",
17574};
17575
17576static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 17577 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
17578 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17579 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 17580 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 17581 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 17582 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 17583 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 17584 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 17585 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 17586 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
17587 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17588 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 17589 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17590 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17591 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17592 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17593 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17594 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 17595 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17596 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17597 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
17598 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17599 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17600 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17601 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 17602 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
17603 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17604 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17605 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 17606 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17607 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17608 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17609 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 17610 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 17611 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17612 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17613 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17614 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 17615 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 17616 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 17617 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 17618 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
17619 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17620 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
17621 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17622 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17623 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 17624 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
17625 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17626 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 17627 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
17628 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17629 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17630 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17631 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17632 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 17633 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 17634 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 17635 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
17636 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17637 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17638 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17639 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
17640 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17641 ALC662_3ST_6ch_DIG),
4dee8baa 17642 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 17643 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
17644 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17645 ALC662_3ST_6ch_DIG),
6227cdce 17646 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 17647 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 17648 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 17649 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 17650 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 17651 ALC662_3ST_6ch_DIG),
dea0a509
TI
17652 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17653 ALC663_ASUS_H13),
7aee6746 17654 SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
bc9f98a9
KY
17655 {}
17656};
17657
17658static struct alc_config_preset alc662_presets[] = {
17659 [ALC662_3ST_2ch_DIG] = {
f9e336f6 17660 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
17661 .init_verbs = { alc662_init_verbs },
17662 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17663 .dac_nids = alc662_dac_nids,
17664 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17665 .dig_in_nid = ALC662_DIGIN_NID,
17666 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17667 .channel_mode = alc662_3ST_2ch_modes,
17668 .input_mux = &alc662_capture_source,
17669 },
17670 [ALC662_3ST_6ch_DIG] = {
f9e336f6 17671 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17672 .init_verbs = { alc662_init_verbs },
17673 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17674 .dac_nids = alc662_dac_nids,
17675 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17676 .dig_in_nid = ALC662_DIGIN_NID,
17677 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17678 .channel_mode = alc662_3ST_6ch_modes,
17679 .need_dac_fix = 1,
17680 .input_mux = &alc662_capture_source,
f12ab1e0 17681 },
bc9f98a9 17682 [ALC662_3ST_6ch] = {
f9e336f6 17683 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17684 .init_verbs = { alc662_init_verbs },
17685 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17686 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17687 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17688 .channel_mode = alc662_3ST_6ch_modes,
17689 .need_dac_fix = 1,
17690 .input_mux = &alc662_capture_source,
f12ab1e0 17691 },
bc9f98a9 17692 [ALC662_5ST_DIG] = {
f9e336f6 17693 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17694 .init_verbs = { alc662_init_verbs },
17695 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17696 .dac_nids = alc662_dac_nids,
17697 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17698 .dig_in_nid = ALC662_DIGIN_NID,
17699 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17700 .channel_mode = alc662_5stack_modes,
17701 .input_mux = &alc662_capture_source,
17702 },
17703 [ALC662_LENOVO_101E] = {
f9e336f6 17704 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
17705 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
17706 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17707 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17708 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17709 .channel_mode = alc662_3ST_2ch_modes,
17710 .input_mux = &alc662_lenovo_101e_capture_source,
17711 .unsol_event = alc662_lenovo_101e_unsol_event,
17712 .init_hook = alc662_lenovo_101e_all_automute,
17713 },
291702f0 17714 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 17715 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
17716 .init_verbs = { alc662_init_verbs,
17717 alc662_eeepc_sue_init_verbs },
17718 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17719 .dac_nids = alc662_dac_nids,
291702f0
KY
17720 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17721 .channel_mode = alc662_3ST_2ch_modes,
291702f0 17722 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17723 .setup = alc662_eeepc_setup,
291702f0
KY
17724 .init_hook = alc662_eeepc_inithook,
17725 },
8c427226 17726 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 17727 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
17728 alc662_chmode_mixer },
17729 .init_verbs = { alc662_init_verbs,
17730 alc662_eeepc_ep20_sue_init_verbs },
17731 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17732 .dac_nids = alc662_dac_nids,
8c427226
KY
17733 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17734 .channel_mode = alc662_3ST_6ch_modes,
17735 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 17736 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17737 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
17738 .init_hook = alc662_eeepc_ep20_inithook,
17739 },
f1d4e28b 17740 [ALC662_ECS] = {
f9e336f6 17741 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
17742 .init_verbs = { alc662_init_verbs,
17743 alc662_ecs_init_verbs },
17744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17745 .dac_nids = alc662_dac_nids,
17746 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17747 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17748 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17749 .setup = alc662_eeepc_setup,
f1d4e28b
KY
17750 .init_hook = alc662_eeepc_inithook,
17751 },
6dda9f4a 17752 [ALC663_ASUS_M51VA] = {
f9e336f6 17753 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
17754 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17755 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17756 .dac_nids = alc662_dac_nids,
17757 .dig_out_nid = ALC662_DIGOUT_NID,
17758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17759 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 17760 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17761 .setup = alc663_m51va_setup,
6dda9f4a
KY
17762 .init_hook = alc663_m51va_inithook,
17763 },
17764 [ALC663_ASUS_G71V] = {
f9e336f6 17765 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
17766 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17767 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17768 .dac_nids = alc662_dac_nids,
17769 .dig_out_nid = ALC662_DIGOUT_NID,
17770 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17771 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 17772 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 17773 .setup = alc663_g71v_setup,
6dda9f4a
KY
17774 .init_hook = alc663_g71v_inithook,
17775 },
17776 [ALC663_ASUS_H13] = {
f9e336f6 17777 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
17778 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17779 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17780 .dac_nids = alc662_dac_nids,
17781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17782 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
17783 .unsol_event = alc663_m51va_unsol_event,
17784 .init_hook = alc663_m51va_inithook,
17785 },
17786 [ALC663_ASUS_G50V] = {
f9e336f6 17787 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
17788 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
17789 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17790 .dac_nids = alc662_dac_nids,
17791 .dig_out_nid = ALC662_DIGOUT_NID,
17792 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17793 .channel_mode = alc662_3ST_6ch_modes,
17794 .input_mux = &alc663_capture_source,
17795 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 17796 .setup = alc663_g50v_setup,
6dda9f4a
KY
17797 .init_hook = alc663_g50v_inithook,
17798 },
f1d4e28b 17799 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
17800 .mixers = { alc663_m51va_mixer },
17801 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
17802 .init_verbs = { alc662_init_verbs,
17803 alc663_21jd_amic_init_verbs },
17804 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17805 .hp_nid = 0x03,
17806 .dac_nids = alc662_dac_nids,
17807 .dig_out_nid = ALC662_DIGOUT_NID,
17808 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17809 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17810 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 17811 .setup = alc663_mode1_setup,
f1d4e28b
KY
17812 .init_hook = alc663_mode1_inithook,
17813 },
17814 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
17815 .mixers = { alc662_1bjd_mixer },
17816 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
17817 .init_verbs = { alc662_init_verbs,
17818 alc662_1bjd_amic_init_verbs },
17819 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17820 .dac_nids = alc662_dac_nids,
17821 .dig_out_nid = ALC662_DIGOUT_NID,
17822 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17823 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17824 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 17825 .setup = alc662_mode2_setup,
f1d4e28b
KY
17826 .init_hook = alc662_mode2_inithook,
17827 },
17828 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
17829 .mixers = { alc663_two_hp_m1_mixer },
17830 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
17831 .init_verbs = { alc662_init_verbs,
17832 alc663_two_hp_amic_m1_init_verbs },
17833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17834 .hp_nid = 0x03,
17835 .dac_nids = alc662_dac_nids,
17836 .dig_out_nid = ALC662_DIGOUT_NID,
17837 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17838 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17839 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 17840 .setup = alc663_mode3_setup,
f1d4e28b
KY
17841 .init_hook = alc663_mode3_inithook,
17842 },
17843 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
17844 .mixers = { alc663_asus_21jd_clfe_mixer },
17845 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
17846 .init_verbs = { alc662_init_verbs,
17847 alc663_21jd_amic_init_verbs},
17848 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17849 .hp_nid = 0x03,
17850 .dac_nids = alc662_dac_nids,
17851 .dig_out_nid = ALC662_DIGOUT_NID,
17852 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17853 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17854 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 17855 .setup = alc663_mode4_setup,
f1d4e28b
KY
17856 .init_hook = alc663_mode4_inithook,
17857 },
17858 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
17859 .mixers = { alc663_asus_15jd_clfe_mixer },
17860 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
17861 .init_verbs = { alc662_init_verbs,
17862 alc663_15jd_amic_init_verbs },
17863 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17864 .hp_nid = 0x03,
17865 .dac_nids = alc662_dac_nids,
17866 .dig_out_nid = ALC662_DIGOUT_NID,
17867 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17868 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17869 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 17870 .setup = alc663_mode5_setup,
f1d4e28b
KY
17871 .init_hook = alc663_mode5_inithook,
17872 },
17873 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
17874 .mixers = { alc663_two_hp_m2_mixer },
17875 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
17876 .init_verbs = { alc662_init_verbs,
17877 alc663_two_hp_amic_m2_init_verbs },
17878 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17879 .hp_nid = 0x03,
17880 .dac_nids = alc662_dac_nids,
17881 .dig_out_nid = ALC662_DIGOUT_NID,
17882 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17883 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17884 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 17885 .setup = alc663_mode6_setup,
f1d4e28b
KY
17886 .init_hook = alc663_mode6_inithook,
17887 },
ebb83eeb
KY
17888 [ALC663_ASUS_MODE7] = {
17889 .mixers = { alc663_mode7_mixer },
17890 .cap_mixer = alc662_auto_capture_mixer,
17891 .init_verbs = { alc662_init_verbs,
17892 alc663_mode7_init_verbs },
17893 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17894 .hp_nid = 0x03,
17895 .dac_nids = alc662_dac_nids,
17896 .dig_out_nid = ALC662_DIGOUT_NID,
17897 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17898 .channel_mode = alc662_3ST_2ch_modes,
17899 .unsol_event = alc663_mode7_unsol_event,
17900 .setup = alc663_mode7_setup,
17901 .init_hook = alc663_mode7_inithook,
17902 },
17903 [ALC663_ASUS_MODE8] = {
17904 .mixers = { alc663_mode8_mixer },
17905 .cap_mixer = alc662_auto_capture_mixer,
17906 .init_verbs = { alc662_init_verbs,
17907 alc663_mode8_init_verbs },
17908 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17909 .hp_nid = 0x03,
17910 .dac_nids = alc662_dac_nids,
17911 .dig_out_nid = ALC662_DIGOUT_NID,
17912 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17913 .channel_mode = alc662_3ST_2ch_modes,
17914 .unsol_event = alc663_mode8_unsol_event,
17915 .setup = alc663_mode8_setup,
17916 .init_hook = alc663_mode8_inithook,
17917 },
622e84cd
KY
17918 [ALC272_DELL] = {
17919 .mixers = { alc663_m51va_mixer },
17920 .cap_mixer = alc272_auto_capture_mixer,
17921 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17922 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17923 .dac_nids = alc662_dac_nids,
17924 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17925 .adc_nids = alc272_adc_nids,
17926 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17927 .capsrc_nids = alc272_capsrc_nids,
17928 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 17929 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17930 .setup = alc663_m51va_setup,
622e84cd
KY
17931 .init_hook = alc663_m51va_inithook,
17932 },
17933 [ALC272_DELL_ZM1] = {
17934 .mixers = { alc663_m51va_mixer },
17935 .cap_mixer = alc662_auto_capture_mixer,
17936 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17937 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17938 .dac_nids = alc662_dac_nids,
17939 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17940 .adc_nids = alc662_adc_nids,
b59bdf3b 17941 .num_adc_nids = 1,
622e84cd
KY
17942 .capsrc_nids = alc662_capsrc_nids,
17943 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 17944 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17945 .setup = alc663_m51va_setup,
622e84cd
KY
17946 .init_hook = alc663_m51va_inithook,
17947 },
9541ba1d
CP
17948 [ALC272_SAMSUNG_NC10] = {
17949 .mixers = { alc272_nc10_mixer },
17950 .init_verbs = { alc662_init_verbs,
17951 alc663_21jd_amic_init_verbs },
17952 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17953 .dac_nids = alc272_dac_nids,
17954 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17955 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 17956 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 17957 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 17958 .setup = alc663_mode4_setup,
9541ba1d
CP
17959 .init_hook = alc663_mode4_inithook,
17960 },
bc9f98a9
KY
17961};
17962
17963
17964/*
17965 * BIOS auto configuration
17966 */
17967
7085ec12
TI
17968/* convert from MIX nid to DAC */
17969static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17970{
17971 if (nid == 0x0f)
17972 return 0x02;
17973 else if (nid >= 0x0c && nid <= 0x0e)
17974 return nid - 0x0c + 0x02;
17975 else
17976 return 0;
17977}
17978
17979/* get MIX nid connected to the given pin targeted to DAC */
17980static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17981 hda_nid_t dac)
17982{
17983 hda_nid_t mix[4];
17984 int i, num;
17985
17986 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17987 for (i = 0; i < num; i++) {
17988 if (alc662_mix_to_dac(mix[i]) == dac)
17989 return mix[i];
17990 }
17991 return 0;
17992}
17993
17994/* look for an empty DAC slot */
17995static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17996{
17997 struct alc_spec *spec = codec->spec;
17998 hda_nid_t srcs[5];
17999 int i, j, num;
18000
18001 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18002 if (num < 0)
18003 return 0;
18004 for (i = 0; i < num; i++) {
18005 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18006 if (!nid)
18007 continue;
18008 for (j = 0; j < spec->multiout.num_dacs; j++)
18009 if (spec->multiout.dac_nids[j] == nid)
18010 break;
18011 if (j >= spec->multiout.num_dacs)
18012 return nid;
18013 }
18014 return 0;
18015}
18016
18017/* fill in the dac_nids table from the parsed pin configuration */
18018static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18019 const struct auto_pin_cfg *cfg)
18020{
18021 struct alc_spec *spec = codec->spec;
18022 int i;
18023 hda_nid_t dac;
18024
18025 spec->multiout.dac_nids = spec->private_dac_nids;
18026 for (i = 0; i < cfg->line_outs; i++) {
18027 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18028 if (!dac)
18029 continue;
18030 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18031 }
18032 return 0;
18033}
18034
0afe5f89 18035static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18036 hda_nid_t nid, unsigned int chs)
18037{
0afe5f89 18038 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18039 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18040}
18041
0afe5f89 18042static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18043 hda_nid_t nid, unsigned int chs)
18044{
0afe5f89 18045 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18046 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18047}
18048
18049#define alc662_add_stereo_vol(spec, pfx, nid) \
18050 alc662_add_vol_ctl(spec, pfx, nid, 3)
18051#define alc662_add_stereo_sw(spec, pfx, nid) \
18052 alc662_add_sw_ctl(spec, pfx, nid, 3)
18053
bc9f98a9 18054/* add playback controls from the parsed DAC table */
7085ec12 18055static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18056 const struct auto_pin_cfg *cfg)
18057{
7085ec12 18058 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18059 static const char *chname[4] = {
18060 "Front", "Surround", NULL /*CLFE*/, "Side"
18061 };
7085ec12 18062 hda_nid_t nid, mix;
bc9f98a9
KY
18063 int i, err;
18064
18065 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18066 nid = spec->multiout.dac_nids[i];
18067 if (!nid)
18068 continue;
18069 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18070 if (!mix)
bc9f98a9 18071 continue;
bc9f98a9
KY
18072 if (i == 2) {
18073 /* Center/LFE */
7085ec12 18074 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18075 if (err < 0)
18076 return err;
7085ec12 18077 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18078 if (err < 0)
18079 return err;
7085ec12 18080 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18081 if (err < 0)
18082 return err;
7085ec12 18083 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18084 if (err < 0)
18085 return err;
18086 } else {
0d884cb9
TI
18087 const char *pfx;
18088 if (cfg->line_outs == 1 &&
18089 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18090 if (cfg->hp_outs)
0d884cb9
TI
18091 pfx = "Speaker";
18092 else
18093 pfx = "PCM";
18094 } else
18095 pfx = chname[i];
7085ec12 18096 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18097 if (err < 0)
18098 return err;
0d884cb9
TI
18099 if (cfg->line_outs == 1 &&
18100 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18101 pfx = "Speaker";
7085ec12 18102 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18103 if (err < 0)
18104 return err;
18105 }
18106 }
18107 return 0;
18108}
18109
18110/* add playback controls for speaker and HP outputs */
7085ec12
TI
18111/* return DAC nid if any new DAC is assigned */
18112static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18113 const char *pfx)
18114{
7085ec12
TI
18115 struct alc_spec *spec = codec->spec;
18116 hda_nid_t nid, mix;
bc9f98a9 18117 int err;
bc9f98a9
KY
18118
18119 if (!pin)
18120 return 0;
7085ec12
TI
18121 nid = alc662_look_for_dac(codec, pin);
18122 if (!nid) {
7085ec12
TI
18123 /* the corresponding DAC is already occupied */
18124 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18125 return 0; /* no way */
18126 /* create a switch only */
0afe5f89 18127 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18128 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18129 }
18130
7085ec12
TI
18131 mix = alc662_dac_to_mix(codec, pin, nid);
18132 if (!mix)
18133 return 0;
18134 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18135 if (err < 0)
18136 return err;
18137 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18138 if (err < 0)
18139 return err;
18140 return nid;
bc9f98a9
KY
18141}
18142
18143/* create playback/capture controls for input pins */
05f5f477 18144#define alc662_auto_create_input_ctls \
4b7348a1 18145 alc882_auto_create_input_ctls
bc9f98a9
KY
18146
18147static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18148 hda_nid_t nid, int pin_type,
7085ec12 18149 hda_nid_t dac)
bc9f98a9 18150{
7085ec12
TI
18151 int i, num;
18152 hda_nid_t srcs[4];
18153
f6c7e546 18154 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18155 /* need the manual connection? */
7085ec12
TI
18156 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18157 if (num <= 1)
18158 return;
18159 for (i = 0; i < num; i++) {
18160 if (alc662_mix_to_dac(srcs[i]) != dac)
18161 continue;
18162 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18163 return;
bc9f98a9
KY
18164 }
18165}
18166
18167static void alc662_auto_init_multi_out(struct hda_codec *codec)
18168{
18169 struct alc_spec *spec = codec->spec;
7085ec12 18170 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18171 int i;
18172
18173 for (i = 0; i <= HDA_SIDE; i++) {
18174 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18175 if (nid)
baba8ee9 18176 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18177 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18178 }
18179}
18180
18181static void alc662_auto_init_hp_out(struct hda_codec *codec)
18182{
18183 struct alc_spec *spec = codec->spec;
18184 hda_nid_t pin;
18185
18186 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18187 if (pin)
18188 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18189 spec->multiout.hp_nid);
f6c7e546
TI
18190 pin = spec->autocfg.speaker_pins[0];
18191 if (pin)
7085ec12
TI
18192 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18193 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18194}
18195
bc9f98a9
KY
18196#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18197
18198static void alc662_auto_init_analog_input(struct hda_codec *codec)
18199{
18200 struct alc_spec *spec = codec->spec;
18201 int i;
18202
18203 for (i = 0; i < AUTO_PIN_LAST; i++) {
18204 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18205 if (alc_is_input_pin(codec, nid)) {
23f0c048 18206 alc_set_input_pin(codec, nid, i);
52ca15b7 18207 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18208 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18209 snd_hda_codec_write(codec, nid, 0,
18210 AC_VERB_SET_AMP_GAIN_MUTE,
18211 AMP_OUT_MUTE);
18212 }
18213 }
18214}
18215
f511b01c
TI
18216#define alc662_auto_init_input_src alc882_auto_init_input_src
18217
bc9f98a9
KY
18218static int alc662_parse_auto_config(struct hda_codec *codec)
18219{
18220 struct alc_spec *spec = codec->spec;
18221 int err;
18222 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18223
18224 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18225 alc662_ignore);
18226 if (err < 0)
18227 return err;
18228 if (!spec->autocfg.line_outs)
18229 return 0; /* can't find valid BIOS pin config */
18230
7085ec12 18231 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18232 if (err < 0)
18233 return err;
7085ec12 18234 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18235 if (err < 0)
18236 return err;
7085ec12 18237 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18238 spec->autocfg.speaker_pins[0],
18239 "Speaker");
18240 if (err < 0)
18241 return err;
7085ec12
TI
18242 if (err)
18243 spec->multiout.extra_out_nid[0] = err;
18244 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18245 "Headphone");
18246 if (err < 0)
18247 return err;
7085ec12
TI
18248 if (err)
18249 spec->multiout.hp_nid = err;
05f5f477 18250 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18251 if (err < 0)
bc9f98a9
KY
18252 return err;
18253
18254 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18255
0852d7a6 18256 if (spec->autocfg.dig_outs)
bc9f98a9
KY
18257 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18258
603c4019 18259 if (spec->kctls.list)
d88897ea 18260 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18261
18262 spec->num_mux_defs = 1;
61b9b9b1 18263 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18264
cec27c89
KY
18265 add_verb(spec, alc662_init_verbs);
18266 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18267 codec->vendor_id == 0x10ec0665)
18268 add_verb(spec, alc663_init_verbs);
18269
18270 if (codec->vendor_id == 0x10ec0272)
18271 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18272
18273 err = alc_auto_add_mic_boost(codec);
18274 if (err < 0)
18275 return err;
18276
6227cdce
KY
18277 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18278 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18279 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18280 else
18281 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18282
8c87286f 18283 return 1;
bc9f98a9
KY
18284}
18285
18286/* additional initialization for auto-configuration model */
18287static void alc662_auto_init(struct hda_codec *codec)
18288{
f6c7e546 18289 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18290 alc662_auto_init_multi_out(codec);
18291 alc662_auto_init_hp_out(codec);
18292 alc662_auto_init_analog_input(codec);
f511b01c 18293 alc662_auto_init_input_src(codec);
f6c7e546 18294 if (spec->unsol_event)
7fb0d78f 18295 alc_inithook(codec);
bc9f98a9
KY
18296}
18297
18298static int patch_alc662(struct hda_codec *codec)
18299{
18300 struct alc_spec *spec;
18301 int err, board_config;
18302
18303 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18304 if (!spec)
18305 return -ENOMEM;
18306
18307 codec->spec = spec;
18308
2c3bf9ab
TI
18309 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18310
274693f3
KY
18311 if (alc_read_coef_idx(codec, 0)==0x8020){
18312 kfree(codec->chip_name);
18313 codec->chip_name = kstrdup("ALC661", GFP_KERNEL);
ac2c92e0
TI
18314 if (!codec->chip_name) {
18315 alc_free(codec);
274693f3 18316 return -ENOMEM;
ac2c92e0 18317 }
274693f3
KY
18318 }
18319
bc9f98a9
KY
18320 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18321 alc662_models,
18322 alc662_cfg_tbl);
18323 if (board_config < 0) {
9a11f1aa
TI
18324 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18325 codec->chip_name);
bc9f98a9
KY
18326 board_config = ALC662_AUTO;
18327 }
18328
18329 if (board_config == ALC662_AUTO) {
18330 /* automatic parse from the BIOS config */
18331 err = alc662_parse_auto_config(codec);
18332 if (err < 0) {
18333 alc_free(codec);
18334 return err;
8c87286f 18335 } else if (!err) {
bc9f98a9
KY
18336 printk(KERN_INFO
18337 "hda_codec: Cannot set up configuration "
18338 "from BIOS. Using base mode...\n");
18339 board_config = ALC662_3ST_2ch_DIG;
18340 }
18341 }
18342
680cd536
KK
18343 err = snd_hda_attach_beep_device(codec, 0x1);
18344 if (err < 0) {
18345 alc_free(codec);
18346 return err;
18347 }
18348
bc9f98a9 18349 if (board_config != ALC662_AUTO)
e9c364c0 18350 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18351
bc9f98a9
KY
18352 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18353 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18354
bc9f98a9
KY
18355 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18356 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18357
dd704698
TI
18358 if (!spec->adc_nids) {
18359 spec->adc_nids = alc662_adc_nids;
18360 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18361 }
18362 if (!spec->capsrc_nids)
18363 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18364
f9e336f6 18365 if (!spec->cap_mixer)
b59bdf3b 18366 set_capture_mixer(codec);
cec27c89
KY
18367
18368 switch (codec->vendor_id) {
18369 case 0x10ec0662:
b9591448 18370 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
cec27c89
KY
18371 break;
18372 case 0x10ec0272:
18373 case 0x10ec0663:
18374 case 0x10ec0665:
b9591448 18375 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
cec27c89
KY
18376 break;
18377 case 0x10ec0273:
18378 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18379 break;
18380 }
2134ea4f
TI
18381 spec->vmaster_nid = 0x02;
18382
bc9f98a9
KY
18383 codec->patch_ops = alc_patch_ops;
18384 if (board_config == ALC662_AUTO)
18385 spec->init_hook = alc662_auto_init;
cb53c626
TI
18386#ifdef CONFIG_SND_HDA_POWER_SAVE
18387 if (!spec->loopback.amplist)
18388 spec->loopback.amplist = alc662_loopbacks;
18389#endif
bc9f98a9
KY
18390
18391 return 0;
18392}
18393
274693f3
KY
18394static int patch_alc888(struct hda_codec *codec)
18395{
18396 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18397 kfree(codec->chip_name);
18398 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18399 if (!codec->chip_name) {
18400 alc_free(codec);
274693f3 18401 return -ENOMEM;
ac2c92e0
TI
18402 }
18403 return patch_alc662(codec);
274693f3 18404 }
ac2c92e0 18405 return patch_alc882(codec);
274693f3
KY
18406}
18407
1da177e4
LT
18408/*
18409 * patch entries
18410 */
1289e9e8 18411static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 18412 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 18413 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 18414 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 18415 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 18416 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 18417 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 18418 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 18419 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 18420 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 18421 .patch = patch_alc861 },
f32610ed
JS
18422 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
18423 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
18424 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 18425 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 18426 .patch = patch_alc882 },
bc9f98a9
KY
18427 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18428 .patch = patch_alc662 },
6dda9f4a 18429 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 18430 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 18431 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
f32610ed 18432 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 18433 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 18434 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 18435 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 18436 .patch = patch_alc882 },
cb308f97 18437 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 18438 .patch = patch_alc882 },
df694daa 18439 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 18440 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 18441 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 18442 .patch = patch_alc882 },
274693f3 18443 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 18444 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 18445 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
18446 {} /* terminator */
18447};
1289e9e8
TI
18448
18449MODULE_ALIAS("snd-hda-codec-id:10ec*");
18450
18451MODULE_LICENSE("GPL");
18452MODULE_DESCRIPTION("Realtek HD-audio codec");
18453
18454static struct hda_codec_preset_list realtek_list = {
18455 .preset = snd_hda_preset_realtek,
18456 .owner = THIS_MODULE,
18457};
18458
18459static int __init patch_realtek_init(void)
18460{
18461 return snd_hda_add_codec_preset(&realtek_list);
18462}
18463
18464static void __exit patch_realtek_exit(void)
18465{
18466 snd_hda_delete_codec_preset(&realtek_list);
18467}
18468
18469module_init(patch_realtek_init)
18470module_exit(patch_realtek_exit)