ALSA: hda - introduce snd_hda_codec_update_cache()
[deliverable/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
da00c244
KY
278struct alc_customize_define {
279 unsigned int sku_cfg;
280 unsigned char port_connectivity;
281 unsigned char check_sum;
282 unsigned char customization;
283 unsigned char external_amp;
284 unsigned int enable_pcbeep:1;
285 unsigned int platform_type:1;
286 unsigned int swap:1;
287 unsigned int override:1;
288};
289
1da177e4
LT
290struct alc_spec {
291 /* codec parameterization */
df694daa 292 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 293 unsigned int num_mixers;
f9e336f6 294 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 295 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 296
2d9c6482 297 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
298 * don't forget NULL
299 * termination!
e9edcee0
TI
300 */
301 unsigned int num_init_verbs;
1da177e4 302
aa563af7 303 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
304 struct hda_pcm_stream *stream_analog_playback;
305 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
306 struct hda_pcm_stream *stream_analog_alt_playback;
307 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 308
aa563af7 309 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
310 struct hda_pcm_stream *stream_digital_playback;
311 struct hda_pcm_stream *stream_digital_capture;
312
313 /* playback */
16ded525
TI
314 struct hda_multi_out multiout; /* playback set-up
315 * max_channels, dacs must be set
316 * dig_out_nid and hp_nid are optional
317 */
6330079f 318 hda_nid_t alt_dac_nid;
6a05ac4a 319 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 320 int dig_out_type;
1da177e4
LT
321
322 /* capture */
323 unsigned int num_adc_nids;
324 hda_nid_t *adc_nids;
e1406348 325 hda_nid_t *capsrc_nids;
16ded525 326 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
327
328 /* capture source */
a1e8d2da 329 unsigned int num_mux_defs;
1da177e4
LT
330 const struct hda_input_mux *input_mux;
331 unsigned int cur_mux[3];
6c819492
TI
332 struct alc_mic_route ext_mic;
333 struct alc_mic_route int_mic;
1da177e4
LT
334
335 /* channel model */
d2a6d7dc 336 const struct hda_channel_mode *channel_mode;
1da177e4 337 int num_channel_mode;
4e195a7b 338 int need_dac_fix;
3b315d70
HM
339 int const_channel_count;
340 int ext_channel_count;
1da177e4
LT
341
342 /* PCM information */
4c5186ed 343 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 344
e9edcee0
TI
345 /* dynamic controls, init_verbs and input_mux */
346 struct auto_pin_cfg autocfg;
da00c244 347 struct alc_customize_define cdefine;
603c4019 348 struct snd_array kctls;
61b9b9b1 349 struct hda_input_mux private_imux[3];
41923e44 350 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
351 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
352 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 353
ae6b813a
TI
354 /* hooks */
355 void (*init_hook)(struct hda_codec *codec);
356 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 357#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 358 void (*power_hook)(struct hda_codec *codec);
f5de24b0 359#endif
ae6b813a 360
834be88d
TI
361 /* for pin sensing */
362 unsigned int sense_updated: 1;
363 unsigned int jack_present: 1;
bec15c3a 364 unsigned int master_sw: 1;
6c819492 365 unsigned int auto_mic:1;
cb53c626 366
e64f14f4
TI
367 /* other flags */
368 unsigned int no_analog :1; /* digital I/O only */
4a79ba34 369 int init_amp;
e64f14f4 370
2134ea4f
TI
371 /* for virtual master */
372 hda_nid_t vmaster_nid;
cb53c626
TI
373#ifdef CONFIG_SND_HDA_POWER_SAVE
374 struct hda_loopback_check loopback;
375#endif
2c3bf9ab
TI
376
377 /* for PLL fix */
378 hda_nid_t pll_nid;
379 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
380};
381
382/*
383 * configuration template - to be copied to the spec instance
384 */
385struct alc_config_preset {
9c7f852e
TI
386 struct snd_kcontrol_new *mixers[5]; /* should be identical size
387 * with spec
388 */
f9e336f6 389 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
390 const struct hda_verb *init_verbs[5];
391 unsigned int num_dacs;
392 hda_nid_t *dac_nids;
393 hda_nid_t dig_out_nid; /* optional */
394 hda_nid_t hp_nid; /* optional */
b25c9da1 395 hda_nid_t *slave_dig_outs;
df694daa
KY
396 unsigned int num_adc_nids;
397 hda_nid_t *adc_nids;
e1406348 398 hda_nid_t *capsrc_nids;
df694daa
KY
399 hda_nid_t dig_in_nid;
400 unsigned int num_channel_mode;
401 const struct hda_channel_mode *channel_mode;
4e195a7b 402 int need_dac_fix;
3b315d70 403 int const_channel_count;
a1e8d2da 404 unsigned int num_mux_defs;
df694daa 405 const struct hda_input_mux *input_mux;
ae6b813a 406 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 407 void (*setup)(struct hda_codec *);
ae6b813a 408 void (*init_hook)(struct hda_codec *);
cb53c626
TI
409#ifdef CONFIG_SND_HDA_POWER_SAVE
410 struct hda_amp_list *loopbacks;
c97259df 411 void (*power_hook)(struct hda_codec *codec);
cb53c626 412#endif
1da177e4
LT
413};
414
1da177e4
LT
415
416/*
417 * input MUX handling
418 */
9c7f852e
TI
419static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
420 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
421{
422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
423 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
424 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
425 if (mux_idx >= spec->num_mux_defs)
426 mux_idx = 0;
5311114d
TI
427 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
428 mux_idx = 0;
a1e8d2da 429 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
430}
431
9c7f852e
TI
432static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
434{
435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436 struct alc_spec *spec = codec->spec;
437 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
438
439 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
440 return 0;
441}
442
9c7f852e
TI
443static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
444 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
445{
446 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
447 struct alc_spec *spec = codec->spec;
cd896c33 448 const struct hda_input_mux *imux;
1da177e4 449 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 450 unsigned int mux_idx;
e1406348
TI
451 hda_nid_t nid = spec->capsrc_nids ?
452 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 453 unsigned int type;
1da177e4 454
cd896c33
TI
455 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
456 imux = &spec->input_mux[mux_idx];
5311114d
TI
457 if (!imux->num_items && mux_idx > 0)
458 imux = &spec->input_mux[0];
cd896c33 459
a22d543a 460 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 461 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
462 /* Matrix-mixer style (e.g. ALC882) */
463 unsigned int *cur_val = &spec->cur_mux[adc_idx];
464 unsigned int i, idx;
465
466 idx = ucontrol->value.enumerated.item[0];
467 if (idx >= imux->num_items)
468 idx = imux->num_items - 1;
469 if (*cur_val == idx)
470 return 0;
471 for (i = 0; i < imux->num_items; i++) {
472 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
473 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
474 imux->items[i].index,
475 HDA_AMP_MUTE, v);
476 }
477 *cur_val = idx;
478 return 1;
479 } else {
480 /* MUX style (e.g. ALC880) */
cd896c33 481 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
482 &spec->cur_mux[adc_idx]);
483 }
484}
e9edcee0 485
1da177e4
LT
486/*
487 * channel mode setting
488 */
9c7f852e
TI
489static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
490 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
491{
492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
493 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
494 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
495 spec->num_channel_mode);
1da177e4
LT
496}
497
9c7f852e
TI
498static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
500{
501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502 struct alc_spec *spec = codec->spec;
d2a6d7dc 503 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 504 spec->num_channel_mode,
3b315d70 505 spec->ext_channel_count);
1da177e4
LT
506}
507
9c7f852e
TI
508static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
509 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
510{
511 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
512 struct alc_spec *spec = codec->spec;
4e195a7b
TI
513 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
514 spec->num_channel_mode,
3b315d70
HM
515 &spec->ext_channel_count);
516 if (err >= 0 && !spec->const_channel_count) {
517 spec->multiout.max_channels = spec->ext_channel_count;
518 if (spec->need_dac_fix)
519 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
520 }
4e195a7b 521 return err;
1da177e4
LT
522}
523
a9430dd8 524/*
4c5186ed 525 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 526 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
527 * being part of a format specifier. Maximum allowed length of a value is
528 * 63 characters plus NULL terminator.
7cf51e48
JW
529 *
530 * Note: some retasking pin complexes seem to ignore requests for input
531 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
532 * are requested. Therefore order this list so that this behaviour will not
533 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
534 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
535 * March 2006.
4c5186ed
JW
536 */
537static char *alc_pin_mode_names[] = {
7cf51e48
JW
538 "Mic 50pc bias", "Mic 80pc bias",
539 "Line in", "Line out", "Headphone out",
4c5186ed
JW
540};
541static unsigned char alc_pin_mode_values[] = {
7cf51e48 542 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
543};
544/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
545 * in the pin being assumed to be exclusively an input or an output pin. In
546 * addition, "input" pins may or may not process the mic bias option
547 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
548 * accept requests for bias as of chip versions up to March 2006) and/or
549 * wiring in the computer.
a9430dd8 550 */
a1e8d2da
JW
551#define ALC_PIN_DIR_IN 0x00
552#define ALC_PIN_DIR_OUT 0x01
553#define ALC_PIN_DIR_INOUT 0x02
554#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
555#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 556
ea1fb29a 557/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
558 * For each direction the minimum and maximum values are given.
559 */
a1e8d2da 560static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
561 { 0, 2 }, /* ALC_PIN_DIR_IN */
562 { 3, 4 }, /* ALC_PIN_DIR_OUT */
563 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
564 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
565 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
566};
567#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
568#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
569#define alc_pin_mode_n_items(_dir) \
570 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
571
9c7f852e
TI
572static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
573 struct snd_ctl_elem_info *uinfo)
a9430dd8 574{
4c5186ed
JW
575 unsigned int item_num = uinfo->value.enumerated.item;
576 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
577
578 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 579 uinfo->count = 1;
4c5186ed
JW
580 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
581
582 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
583 item_num = alc_pin_mode_min(dir);
584 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
585 return 0;
586}
587
9c7f852e
TI
588static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
589 struct snd_ctl_elem_value *ucontrol)
a9430dd8 590{
4c5186ed 591 unsigned int i;
a9430dd8
JW
592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
593 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 594 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 595 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
596 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
597 AC_VERB_GET_PIN_WIDGET_CONTROL,
598 0x00);
a9430dd8 599
4c5186ed
JW
600 /* Find enumerated value for current pinctl setting */
601 i = alc_pin_mode_min(dir);
4b35d2ca 602 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 603 i++;
9c7f852e 604 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
605 return 0;
606}
607
9c7f852e
TI
608static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_value *ucontrol)
a9430dd8 610{
4c5186ed 611 signed int change;
a9430dd8
JW
612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
614 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
615 long val = *ucontrol->value.integer.value;
9c7f852e
TI
616 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
617 AC_VERB_GET_PIN_WIDGET_CONTROL,
618 0x00);
a9430dd8 619
f12ab1e0 620 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
621 val = alc_pin_mode_min(dir);
622
623 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
624 if (change) {
625 /* Set pin mode to that requested */
82beb8fd
TI
626 snd_hda_codec_write_cache(codec, nid, 0,
627 AC_VERB_SET_PIN_WIDGET_CONTROL,
628 alc_pin_mode_values[val]);
cdcd9268 629
ea1fb29a 630 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
631 * for the requested pin mode. Enum values of 2 or less are
632 * input modes.
633 *
634 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
635 * reduces noise slightly (particularly on input) so we'll
636 * do it. However, having both input and output buffers
637 * enabled simultaneously doesn't seem to be problematic if
638 * this turns out to be necessary in the future.
cdcd9268
JW
639 */
640 if (val <= 2) {
47fd830a
TI
641 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
642 HDA_AMP_MUTE, HDA_AMP_MUTE);
643 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
644 HDA_AMP_MUTE, 0);
cdcd9268 645 } else {
47fd830a
TI
646 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
647 HDA_AMP_MUTE, HDA_AMP_MUTE);
648 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
649 HDA_AMP_MUTE, 0);
cdcd9268
JW
650 }
651 }
a9430dd8
JW
652 return change;
653}
654
4c5186ed 655#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 656 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 657 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
658 .info = alc_pin_mode_info, \
659 .get = alc_pin_mode_get, \
660 .put = alc_pin_mode_put, \
661 .private_value = nid | (dir<<16) }
df694daa 662
5c8f858d
JW
663/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
664 * together using a mask with more than one bit set. This control is
665 * currently used only by the ALC260 test model. At this stage they are not
666 * needed for any "production" models.
667 */
668#ifdef CONFIG_SND_DEBUG
a5ce8890 669#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 670
9c7f852e
TI
671static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
672 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
673{
674 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
675 hda_nid_t nid = kcontrol->private_value & 0xffff;
676 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
677 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
678 unsigned int val = snd_hda_codec_read(codec, nid, 0,
679 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
680
681 *valp = (val & mask) != 0;
682 return 0;
683}
9c7f852e
TI
684static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
686{
687 signed int change;
688 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
689 hda_nid_t nid = kcontrol->private_value & 0xffff;
690 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
691 long val = *ucontrol->value.integer.value;
9c7f852e
TI
692 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
693 AC_VERB_GET_GPIO_DATA,
694 0x00);
5c8f858d
JW
695
696 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
697 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
698 if (val == 0)
5c8f858d
JW
699 gpio_data &= ~mask;
700 else
701 gpio_data |= mask;
82beb8fd
TI
702 snd_hda_codec_write_cache(codec, nid, 0,
703 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
704
705 return change;
706}
707#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
708 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 709 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
710 .info = alc_gpio_data_info, \
711 .get = alc_gpio_data_get, \
712 .put = alc_gpio_data_put, \
713 .private_value = nid | (mask<<16) }
714#endif /* CONFIG_SND_DEBUG */
715
92621f13
JW
716/* A switch control to allow the enabling of the digital IO pins on the
717 * ALC260. This is incredibly simplistic; the intention of this control is
718 * to provide something in the test model allowing digital outputs to be
719 * identified if present. If models are found which can utilise these
720 * outputs a more complete mixer control can be devised for those models if
721 * necessary.
722 */
723#ifdef CONFIG_SND_DEBUG
a5ce8890 724#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 725
9c7f852e
TI
726static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
728{
729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
730 hda_nid_t nid = kcontrol->private_value & 0xffff;
731 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
732 long *valp = ucontrol->value.integer.value;
9c7f852e 733 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 734 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
735
736 *valp = (val & mask) != 0;
737 return 0;
738}
9c7f852e
TI
739static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
740 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
741{
742 signed int change;
743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 hda_nid_t nid = kcontrol->private_value & 0xffff;
745 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
746 long val = *ucontrol->value.integer.value;
9c7f852e 747 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 748 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 749 0x00);
92621f13
JW
750
751 /* Set/unset the masked control bit(s) as needed */
9c7f852e 752 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
753 if (val==0)
754 ctrl_data &= ~mask;
755 else
756 ctrl_data |= mask;
82beb8fd
TI
757 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
758 ctrl_data);
92621f13
JW
759
760 return change;
761}
762#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 764 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
765 .info = alc_spdif_ctrl_info, \
766 .get = alc_spdif_ctrl_get, \
767 .put = alc_spdif_ctrl_put, \
768 .private_value = nid | (mask<<16) }
769#endif /* CONFIG_SND_DEBUG */
770
f8225f6d
JW
771/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
772 * Again, this is only used in the ALC26x test models to help identify when
773 * the EAPD line must be asserted for features to work.
774 */
775#ifdef CONFIG_SND_DEBUG
776#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
777
778static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
779 struct snd_ctl_elem_value *ucontrol)
780{
781 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
782 hda_nid_t nid = kcontrol->private_value & 0xffff;
783 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
784 long *valp = ucontrol->value.integer.value;
785 unsigned int val = snd_hda_codec_read(codec, nid, 0,
786 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
787
788 *valp = (val & mask) != 0;
789 return 0;
790}
791
792static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
794{
795 int change;
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long val = *ucontrol->value.integer.value;
800 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE,
802 0x00);
803
804 /* Set/unset the masked control bit(s) as needed */
805 change = (!val ? 0 : mask) != (ctrl_data & mask);
806 if (!val)
807 ctrl_data &= ~mask;
808 else
809 ctrl_data |= mask;
810 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
811 ctrl_data);
812
813 return change;
814}
815
816#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
817 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 818 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
819 .info = alc_eapd_ctrl_info, \
820 .get = alc_eapd_ctrl_get, \
821 .put = alc_eapd_ctrl_put, \
822 .private_value = nid | (mask<<16) }
823#endif /* CONFIG_SND_DEBUG */
824
23f0c048
TI
825/*
826 * set up the input pin config (depending on the given auto-pin type)
827 */
828static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
829 int auto_pin_type)
830{
831 unsigned int val = PIN_IN;
832
833 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
834 unsigned int pincap;
1327a32b 835 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
836 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
837 if (pincap & AC_PINCAP_VREF_80)
838 val = PIN_VREF80;
461c6c3a
TI
839 else if (pincap & AC_PINCAP_VREF_50)
840 val = PIN_VREF50;
841 else if (pincap & AC_PINCAP_VREF_100)
842 val = PIN_VREF100;
843 else if (pincap & AC_PINCAP_VREF_GRD)
844 val = PIN_VREFGRD;
23f0c048
TI
845 }
846 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
847}
848
d88897ea
TI
849/*
850 */
851static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
852{
853 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
854 return;
855 spec->mixers[spec->num_mixers++] = mix;
856}
857
858static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
859{
860 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
861 return;
862 spec->init_verbs[spec->num_init_verbs++] = verb;
863}
864
df694daa
KY
865/*
866 * set up from the preset table
867 */
e9c364c0 868static void setup_preset(struct hda_codec *codec,
9c7f852e 869 const struct alc_config_preset *preset)
df694daa 870{
e9c364c0 871 struct alc_spec *spec = codec->spec;
df694daa
KY
872 int i;
873
874 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 875 add_mixer(spec, preset->mixers[i]);
f9e336f6 876 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
877 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
878 i++)
d88897ea 879 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 880
df694daa
KY
881 spec->channel_mode = preset->channel_mode;
882 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 883 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 884 spec->const_channel_count = preset->const_channel_count;
df694daa 885
3b315d70
HM
886 if (preset->const_channel_count)
887 spec->multiout.max_channels = preset->const_channel_count;
888 else
889 spec->multiout.max_channels = spec->channel_mode[0].channels;
890 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
891
892 spec->multiout.num_dacs = preset->num_dacs;
893 spec->multiout.dac_nids = preset->dac_nids;
894 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 895 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 896 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 897
a1e8d2da 898 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 899 if (!spec->num_mux_defs)
a1e8d2da 900 spec->num_mux_defs = 1;
df694daa
KY
901 spec->input_mux = preset->input_mux;
902
903 spec->num_adc_nids = preset->num_adc_nids;
904 spec->adc_nids = preset->adc_nids;
e1406348 905 spec->capsrc_nids = preset->capsrc_nids;
df694daa 906 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
907
908 spec->unsol_event = preset->unsol_event;
909 spec->init_hook = preset->init_hook;
cb53c626 910#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 911 spec->power_hook = preset->power_hook;
cb53c626
TI
912 spec->loopback.amplist = preset->loopbacks;
913#endif
e9c364c0
TI
914
915 if (preset->setup)
916 preset->setup(codec);
df694daa
KY
917}
918
bc9f98a9
KY
919/* Enable GPIO mask and set output */
920static struct hda_verb alc_gpio1_init_verbs[] = {
921 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
922 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
923 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
924 { }
925};
926
927static struct hda_verb alc_gpio2_init_verbs[] = {
928 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
929 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
930 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
931 { }
932};
933
bdd148a3
KY
934static struct hda_verb alc_gpio3_init_verbs[] = {
935 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
936 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
937 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
938 { }
939};
940
2c3bf9ab
TI
941/*
942 * Fix hardware PLL issue
943 * On some codecs, the analog PLL gating control must be off while
944 * the default value is 1.
945 */
946static void alc_fix_pll(struct hda_codec *codec)
947{
948 struct alc_spec *spec = codec->spec;
949 unsigned int val;
950
951 if (!spec->pll_nid)
952 return;
953 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
954 spec->pll_coef_idx);
955 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
956 AC_VERB_GET_PROC_COEF, 0);
957 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
958 spec->pll_coef_idx);
959 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
960 val & ~(1 << spec->pll_coef_bit));
961}
962
963static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
964 unsigned int coef_idx, unsigned int coef_bit)
965{
966 struct alc_spec *spec = codec->spec;
967 spec->pll_nid = nid;
968 spec->pll_coef_idx = coef_idx;
969 spec->pll_coef_bit = coef_bit;
970 alc_fix_pll(codec);
971}
972
a9fd4f3f 973static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
974{
975 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
976 unsigned int nid = spec->autocfg.hp_pins[0];
977 int i;
c9b58006 978
ad87c64f
TI
979 if (!nid)
980 return;
864f92be 981 spec->jack_present = snd_hda_jack_detect(codec, nid);
a9fd4f3f
TI
982 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
983 nid = spec->autocfg.speaker_pins[i];
984 if (!nid)
985 break;
986 snd_hda_codec_write(codec, nid, 0,
987 AC_VERB_SET_PIN_WIDGET_CONTROL,
988 spec->jack_present ? 0 : PIN_OUT);
989 }
c9b58006
KY
990}
991
6c819492
TI
992static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
993 hda_nid_t nid)
994{
995 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
996 int i, nums;
997
998 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
999 for (i = 0; i < nums; i++)
1000 if (conn[i] == nid)
1001 return i;
1002 return -1;
1003}
1004
7fb0d78f
KY
1005static void alc_mic_automute(struct hda_codec *codec)
1006{
1007 struct alc_spec *spec = codec->spec;
6c819492
TI
1008 struct alc_mic_route *dead, *alive;
1009 unsigned int present, type;
1010 hda_nid_t cap_nid;
1011
b59bdf3b
TI
1012 if (!spec->auto_mic)
1013 return;
6c819492
TI
1014 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1015 return;
1016 if (snd_BUG_ON(!spec->adc_nids))
1017 return;
1018
1019 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1020
864f92be 1021 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1022 if (present) {
1023 alive = &spec->ext_mic;
1024 dead = &spec->int_mic;
1025 } else {
1026 alive = &spec->int_mic;
1027 dead = &spec->ext_mic;
1028 }
1029
6c819492
TI
1030 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1031 if (type == AC_WID_AUD_MIX) {
1032 /* Matrix-mixer style (e.g. ALC882) */
1033 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1034 alive->mux_idx,
1035 HDA_AMP_MUTE, 0);
1036 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1037 dead->mux_idx,
1038 HDA_AMP_MUTE, HDA_AMP_MUTE);
1039 } else {
1040 /* MUX style (e.g. ALC880) */
1041 snd_hda_codec_write_cache(codec, cap_nid, 0,
1042 AC_VERB_SET_CONNECT_SEL,
1043 alive->mux_idx);
1044 }
1045
1046 /* FIXME: analog mixer */
7fb0d78f
KY
1047}
1048
c9b58006
KY
1049/* unsolicited event for HP jack sensing */
1050static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1051{
1052 if (codec->vendor_id == 0x10ec0880)
1053 res >>= 28;
1054 else
1055 res >>= 26;
a9fd4f3f
TI
1056 switch (res) {
1057 case ALC880_HP_EVENT:
1058 alc_automute_pin(codec);
1059 break;
1060 case ALC880_MIC_EVENT:
7fb0d78f 1061 alc_mic_automute(codec);
a9fd4f3f
TI
1062 break;
1063 }
7fb0d78f
KY
1064}
1065
1066static void alc_inithook(struct hda_codec *codec)
1067{
a9fd4f3f 1068 alc_automute_pin(codec);
7fb0d78f 1069 alc_mic_automute(codec);
c9b58006
KY
1070}
1071
f9423e7a
KY
1072/* additional initialization for ALC888 variants */
1073static void alc888_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, 0);
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);
37db623a 1080 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1081 /* alc888S-VC */
1082 snd_hda_codec_read(codec, 0x20, 0,
1083 AC_VERB_SET_PROC_COEF, 0x830);
1084 else
1085 /* alc888-VB */
1086 snd_hda_codec_read(codec, 0x20, 0,
1087 AC_VERB_SET_PROC_COEF, 0x3030);
1088}
1089
87a8c370
JK
1090static void alc889_coef_init(struct hda_codec *codec)
1091{
1092 unsigned int tmp;
1093
1094 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1095 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1096 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1098}
1099
3fb4a508
TI
1100/* turn on/off EAPD control (only if available) */
1101static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1102{
1103 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1104 return;
1105 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1106 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1107 on ? 2 : 0);
1108}
1109
4a79ba34 1110static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1111{
4a79ba34 1112 unsigned int tmp;
bc9f98a9 1113
4a79ba34
TI
1114 switch (type) {
1115 case ALC_INIT_GPIO1:
bc9f98a9
KY
1116 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1117 break;
4a79ba34 1118 case ALC_INIT_GPIO2:
bc9f98a9
KY
1119 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1120 break;
4a79ba34 1121 case ALC_INIT_GPIO3:
bdd148a3
KY
1122 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1123 break;
4a79ba34 1124 case ALC_INIT_DEFAULT:
bdd148a3 1125 switch (codec->vendor_id) {
c9b58006 1126 case 0x10ec0260:
3fb4a508
TI
1127 set_eapd(codec, 0x0f, 1);
1128 set_eapd(codec, 0x10, 1);
c9b58006
KY
1129 break;
1130 case 0x10ec0262:
bdd148a3
KY
1131 case 0x10ec0267:
1132 case 0x10ec0268:
c9b58006 1133 case 0x10ec0269:
3fb4a508 1134 case 0x10ec0270:
c6e8f2da 1135 case 0x10ec0272:
f9423e7a
KY
1136 case 0x10ec0660:
1137 case 0x10ec0662:
1138 case 0x10ec0663:
c9b58006 1139 case 0x10ec0862:
20a3a05d 1140 case 0x10ec0889:
3fb4a508
TI
1141 set_eapd(codec, 0x14, 1);
1142 set_eapd(codec, 0x15, 1);
c9b58006 1143 break;
bdd148a3 1144 }
c9b58006
KY
1145 switch (codec->vendor_id) {
1146 case 0x10ec0260:
1147 snd_hda_codec_write(codec, 0x1a, 0,
1148 AC_VERB_SET_COEF_INDEX, 7);
1149 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1150 AC_VERB_GET_PROC_COEF, 0);
1151 snd_hda_codec_write(codec, 0x1a, 0,
1152 AC_VERB_SET_COEF_INDEX, 7);
1153 snd_hda_codec_write(codec, 0x1a, 0,
1154 AC_VERB_SET_PROC_COEF,
1155 tmp | 0x2010);
1156 break;
1157 case 0x10ec0262:
1158 case 0x10ec0880:
1159 case 0x10ec0882:
1160 case 0x10ec0883:
1161 case 0x10ec0885:
4a5a4c56 1162 case 0x10ec0887:
20a3a05d 1163 case 0x10ec0889:
87a8c370 1164 alc889_coef_init(codec);
c9b58006 1165 break;
f9423e7a 1166 case 0x10ec0888:
4a79ba34 1167 alc888_coef_init(codec);
f9423e7a 1168 break;
0aea778e 1169#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1170 case 0x10ec0267:
1171 case 0x10ec0268:
1172 snd_hda_codec_write(codec, 0x20, 0,
1173 AC_VERB_SET_COEF_INDEX, 7);
1174 tmp = snd_hda_codec_read(codec, 0x20, 0,
1175 AC_VERB_GET_PROC_COEF, 0);
1176 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1177 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1178 snd_hda_codec_write(codec, 0x20, 0,
1179 AC_VERB_SET_PROC_COEF,
1180 tmp | 0x3000);
1181 break;
0aea778e 1182#endif /* XXX */
bc9f98a9 1183 }
4a79ba34
TI
1184 break;
1185 }
1186}
1187
1188static void alc_init_auto_hp(struct hda_codec *codec)
1189{
1190 struct alc_spec *spec = codec->spec;
1191
1192 if (!spec->autocfg.hp_pins[0])
1193 return;
1194
1195 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1196 if (spec->autocfg.line_out_pins[0] &&
1197 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1198 spec->autocfg.speaker_pins[0] =
1199 spec->autocfg.line_out_pins[0];
1200 else
1201 return;
1202 }
1203
2a2ed0df
TI
1204 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1205 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1206 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1207 AC_VERB_SET_UNSOLICITED_ENABLE,
1208 AC_USRSP_EN | ALC880_HP_EVENT);
1209 spec->unsol_event = alc_sku_unsol_event;
1210}
1211
6c819492
TI
1212static void alc_init_auto_mic(struct hda_codec *codec)
1213{
1214 struct alc_spec *spec = codec->spec;
1215 struct auto_pin_cfg *cfg = &spec->autocfg;
1216 hda_nid_t fixed, ext;
1217 int i;
1218
1219 /* there must be only two mic inputs exclusively */
1220 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1221 if (cfg->input_pins[i])
1222 return;
1223
1224 fixed = ext = 0;
1225 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1226 hda_nid_t nid = cfg->input_pins[i];
1227 unsigned int defcfg;
1228 if (!nid)
1229 return;
1230 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1231 switch (get_defcfg_connect(defcfg)) {
1232 case AC_JACK_PORT_FIXED:
1233 if (fixed)
1234 return; /* already occupied */
1235 fixed = nid;
1236 break;
1237 case AC_JACK_PORT_COMPLEX:
1238 if (ext)
1239 return; /* already occupied */
1240 ext = nid;
1241 break;
1242 default:
1243 return; /* invalid entry */
1244 }
1245 }
eaa9b3a7
TI
1246 if (!ext || !fixed)
1247 return;
6c819492
TI
1248 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1249 return; /* no unsol support */
1250 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1251 ext, fixed);
1252 spec->ext_mic.pin = ext;
1253 spec->int_mic.pin = fixed;
1254 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1255 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1256 spec->auto_mic = 1;
1257 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1258 AC_VERB_SET_UNSOLICITED_ENABLE,
1259 AC_USRSP_EN | ALC880_MIC_EVENT);
1260 spec->unsol_event = alc_sku_unsol_event;
1261}
1262
da00c244
KY
1263static int alc_auto_parse_customize_define(struct hda_codec *codec)
1264{
1265 unsigned int ass, tmp, i;
7fb56223 1266 unsigned nid = 0;
da00c244
KY
1267 struct alc_spec *spec = codec->spec;
1268
1269 ass = codec->subsystem_id & 0xffff;
1270 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1271 goto do_sku;
1272
1273 nid = 0x1d;
1274 if (codec->vendor_id == 0x10ec0260)
1275 nid = 0x17;
1276 ass = snd_hda_codec_get_pincfg(codec, nid);
1277
1278 if (!(ass & 1)) {
1279 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1280 codec->chip_name, ass);
1281 return -1;
1282 }
1283
1284 /* check sum */
1285 tmp = 0;
1286 for (i = 1; i < 16; i++) {
1287 if ((ass >> i) & 1)
1288 tmp++;
1289 }
1290 if (((ass >> 16) & 0xf) != tmp)
1291 return -1;
1292
1293 spec->cdefine.port_connectivity = ass >> 30;
1294 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1295 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1296 spec->cdefine.customization = ass >> 8;
1297do_sku:
1298 spec->cdefine.sku_cfg = ass;
1299 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1300 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1301 spec->cdefine.swap = (ass & 0x2) >> 1;
1302 spec->cdefine.override = ass & 0x1;
1303
1304 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1305 nid, spec->cdefine.sku_cfg);
1306 snd_printd("SKU: port_connectivity=0x%x\n",
1307 spec->cdefine.port_connectivity);
1308 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1309 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1310 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1311 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1312 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1313 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1314 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1315
1316 return 0;
1317}
1318
4a79ba34
TI
1319/* check subsystem ID and set up device-specific initialization;
1320 * return 1 if initialized, 0 if invalid SSID
1321 */
1322/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1323 * 31 ~ 16 : Manufacture ID
1324 * 15 ~ 8 : SKU ID
1325 * 7 ~ 0 : Assembly ID
1326 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1327 */
1328static int alc_subsystem_id(struct hda_codec *codec,
1329 hda_nid_t porta, hda_nid_t porte,
6227cdce 1330 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1331{
1332 unsigned int ass, tmp, i;
1333 unsigned nid;
1334 struct alc_spec *spec = codec->spec;
1335
1336 ass = codec->subsystem_id & 0xffff;
1337 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1338 goto do_sku;
1339
1340 /* invalid SSID, check the special NID pin defcfg instead */
1341 /*
def319f9 1342 * 31~30 : port connectivity
4a79ba34
TI
1343 * 29~21 : reserve
1344 * 20 : PCBEEP input
1345 * 19~16 : Check sum (15:1)
1346 * 15~1 : Custom
1347 * 0 : override
1348 */
1349 nid = 0x1d;
1350 if (codec->vendor_id == 0x10ec0260)
1351 nid = 0x17;
1352 ass = snd_hda_codec_get_pincfg(codec, nid);
1353 snd_printd("realtek: No valid SSID, "
1354 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1355 ass, nid);
6227cdce 1356 if (!(ass & 1))
4a79ba34
TI
1357 return 0;
1358 if ((ass >> 30) != 1) /* no physical connection */
1359 return 0;
1360
1361 /* check sum */
1362 tmp = 0;
1363 for (i = 1; i < 16; i++) {
1364 if ((ass >> i) & 1)
1365 tmp++;
1366 }
1367 if (((ass >> 16) & 0xf) != tmp)
1368 return 0;
1369do_sku:
1370 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1371 ass & 0xffff, codec->vendor_id);
1372 /*
1373 * 0 : override
1374 * 1 : Swap Jack
1375 * 2 : 0 --> Desktop, 1 --> Laptop
1376 * 3~5 : External Amplifier control
1377 * 7~6 : Reserved
1378 */
1379 tmp = (ass & 0x38) >> 3; /* external Amp control */
1380 switch (tmp) {
1381 case 1:
1382 spec->init_amp = ALC_INIT_GPIO1;
1383 break;
1384 case 3:
1385 spec->init_amp = ALC_INIT_GPIO2;
1386 break;
1387 case 7:
1388 spec->init_amp = ALC_INIT_GPIO3;
1389 break;
1390 case 5:
1391 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1392 break;
1393 }
ea1fb29a 1394
8c427226 1395 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1396 * when the external headphone out jack is plugged"
1397 */
8c427226 1398 if (!(ass & 0x8000))
4a79ba34 1399 return 1;
c9b58006
KY
1400 /*
1401 * 10~8 : Jack location
1402 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1403 * 14~13: Resvered
1404 * 15 : 1 --> enable the function "Mute internal speaker
1405 * when the external headphone out jack is plugged"
1406 */
c9b58006 1407 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1408 hda_nid_t nid;
c9b58006
KY
1409 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1410 if (tmp == 0)
01d4825d 1411 nid = porta;
c9b58006 1412 else if (tmp == 1)
01d4825d 1413 nid = porte;
c9b58006 1414 else if (tmp == 2)
01d4825d 1415 nid = portd;
6227cdce
KY
1416 else if (tmp == 3)
1417 nid = porti;
c9b58006 1418 else
4a79ba34 1419 return 1;
01d4825d
TI
1420 for (i = 0; i < spec->autocfg.line_outs; i++)
1421 if (spec->autocfg.line_out_pins[i] == nid)
1422 return 1;
1423 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1424 }
1425
4a79ba34 1426 alc_init_auto_hp(codec);
6c819492 1427 alc_init_auto_mic(codec);
4a79ba34
TI
1428 return 1;
1429}
ea1fb29a 1430
4a79ba34 1431static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1432 hda_nid_t porta, hda_nid_t porte,
1433 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1434{
6227cdce 1435 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1436 struct alc_spec *spec = codec->spec;
1437 snd_printd("realtek: "
1438 "Enable default setup for auto mode as fallback\n");
1439 spec->init_amp = ALC_INIT_DEFAULT;
1440 alc_init_auto_hp(codec);
6c819492 1441 alc_init_auto_mic(codec);
4a79ba34 1442 }
bc9f98a9
KY
1443}
1444
f95474ec 1445/*
f8f25ba3 1446 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1447 */
1448
1449struct alc_pincfg {
1450 hda_nid_t nid;
1451 u32 val;
1452};
1453
f8f25ba3
TI
1454struct alc_fixup {
1455 const struct alc_pincfg *pins;
1456 const struct hda_verb *verbs;
1457};
1458
1459static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1460 const struct snd_pci_quirk *quirk,
f8f25ba3 1461 const struct alc_fixup *fix)
f95474ec
TI
1462{
1463 const struct alc_pincfg *cfg;
1464
1465 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1466 if (!quirk)
1467 return;
1468
f8f25ba3
TI
1469 fix += quirk->value;
1470 cfg = fix->pins;
1471 if (cfg) {
1472 for (; cfg->nid; cfg++)
1473 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1474 }
1475 if (fix->verbs)
1476 add_verb(codec->spec, fix->verbs);
f95474ec
TI
1477}
1478
274693f3
KY
1479static int alc_read_coef_idx(struct hda_codec *codec,
1480 unsigned int coef_idx)
1481{
1482 unsigned int val;
1483 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1484 coef_idx);
1485 val = snd_hda_codec_read(codec, 0x20, 0,
1486 AC_VERB_GET_PROC_COEF, 0);
1487 return val;
1488}
1489
ef8ef5fb
VP
1490/*
1491 * ALC888
1492 */
1493
1494/*
1495 * 2ch mode
1496 */
1497static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1498/* Mic-in jack as mic in */
1499 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1500 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1501/* Line-in jack as Line in */
1502 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1503 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1504/* Line-Out as Front */
1505 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1506 { } /* end */
1507};
1508
1509/*
1510 * 4ch mode
1511 */
1512static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1513/* Mic-in jack as mic in */
1514 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1515 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1516/* Line-in jack as Surround */
1517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1518 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1519/* Line-Out as Front */
1520 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1521 { } /* end */
1522};
1523
1524/*
1525 * 6ch mode
1526 */
1527static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1528/* Mic-in jack as CLFE */
1529 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1530 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1531/* Line-in jack as Surround */
1532 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1533 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1534/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1535 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1536 { } /* end */
1537};
1538
1539/*
1540 * 8ch mode
1541 */
1542static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1543/* Mic-in jack as CLFE */
1544 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1545 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1546/* Line-in jack as Surround */
1547 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1548 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1549/* Line-Out as Side */
1550 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1551 { } /* end */
1552};
1553
1554static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1555 { 2, alc888_4ST_ch2_intel_init },
1556 { 4, alc888_4ST_ch4_intel_init },
1557 { 6, alc888_4ST_ch6_intel_init },
1558 { 8, alc888_4ST_ch8_intel_init },
1559};
1560
1561/*
1562 * ALC888 Fujitsu Siemens Amillo xa3530
1563 */
1564
1565static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1566/* Front Mic: set to PIN_IN (empty by default) */
1567 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1568/* Connect Internal HP to Front */
1569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1571 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1572/* Connect Bass HP to Front */
1573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1575 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1576/* Connect Line-Out side jack (SPDIF) to Side */
1577 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1578 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1579 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1580/* Connect Mic jack to CLFE */
1581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1583 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1584/* Connect Line-in jack to Surround */
1585 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1586 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1587 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1588/* Connect HP out jack to Front */
1589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1590 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1591 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1592/* Enable unsolicited event for HP jack and Line-out jack */
1593 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1594 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1595 {}
1596};
1597
a9fd4f3f 1598static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1599{
a9fd4f3f 1600 struct alc_spec *spec = codec->spec;
864f92be 1601 unsigned int mute;
a9fd4f3f
TI
1602 hda_nid_t nid;
1603 int i;
1604
1605 spec->jack_present = 0;
1606 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1607 nid = spec->autocfg.hp_pins[i];
1608 if (!nid)
1609 break;
864f92be 1610 if (snd_hda_jack_detect(codec, nid)) {
a9fd4f3f
TI
1611 spec->jack_present = 1;
1612 break;
1613 }
1614 }
1615
1616 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1617 /* Toggle internal speakers muting */
a9fd4f3f
TI
1618 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1619 nid = spec->autocfg.speaker_pins[i];
1620 if (!nid)
1621 break;
1622 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1623 HDA_AMP_MUTE, mute);
1624 }
ef8ef5fb
VP
1625}
1626
a9fd4f3f
TI
1627static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1628 unsigned int res)
ef8ef5fb 1629{
a9fd4f3f
TI
1630 if (codec->vendor_id == 0x10ec0880)
1631 res >>= 28;
1632 else
1633 res >>= 26;
1634 if (res == ALC880_HP_EVENT)
1635 alc_automute_amp(codec);
ef8ef5fb
VP
1636}
1637
4f5d1706 1638static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1639{
1640 struct alc_spec *spec = codec->spec;
1641
1642 spec->autocfg.hp_pins[0] = 0x15;
1643 spec->autocfg.speaker_pins[0] = 0x14;
1644 spec->autocfg.speaker_pins[1] = 0x16;
1645 spec->autocfg.speaker_pins[2] = 0x17;
1646 spec->autocfg.speaker_pins[3] = 0x19;
1647 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1648}
1649
1650static void alc889_intel_init_hook(struct hda_codec *codec)
1651{
1652 alc889_coef_init(codec);
4f5d1706 1653 alc_automute_amp(codec);
6732bd0d
WF
1654}
1655
4f5d1706 1656static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1657{
1658 struct alc_spec *spec = codec->spec;
1659
1660 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1661 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1662 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1663 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1664}
ef8ef5fb 1665
5b2d1eca
VP
1666/*
1667 * ALC888 Acer Aspire 4930G model
1668 */
1669
1670static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1671/* Front Mic: set to PIN_IN (empty by default) */
1672 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1673/* Unselect Front Mic by default in input mixer 3 */
1674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1675/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1676 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1677/* Connect Internal HP to front */
1678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1681/* Connect HP out to front */
1682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1685 { }
1686};
1687
d2fd4b09
TV
1688/*
1689 * ALC888 Acer Aspire 6530G model
1690 */
1691
1692static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1693/* Bias voltage on for external mic port */
1694 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1695/* Front Mic: set to PIN_IN (empty by default) */
1696 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1697/* Unselect Front Mic by default in input mixer 3 */
1698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1699/* Enable unsolicited event for HP jack */
1700 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1701/* Enable speaker output */
1702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704/* Enable headphone output */
1705 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1706 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1707 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1708 { }
1709};
1710
3b315d70 1711/*
018df418 1712 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1713 */
1714
018df418 1715static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1716/* Front Mic: set to PIN_IN (empty by default) */
1717 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1718/* Unselect Front Mic by default in input mixer 3 */
1719 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1720/* Enable unsolicited event for HP jack */
1721 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1722/* Connect Internal Front to Front */
1723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1726/* Connect Internal Rear to Rear */
1727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1728 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1729 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1730/* Connect Internal CLFE to CLFE */
1731 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1732 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1733 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1734/* Connect HP out to Front */
018df418 1735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1737 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1738/* Enable all DACs */
1739/* DAC DISABLE/MUTE 1? */
1740/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1741 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1742 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1743/* DAC DISABLE/MUTE 2? */
1744/* some bit here disables the other DACs. Init=0x4900 */
1745 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1746 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1747/* DMIC fix
1748 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1749 * which makes the stereo useless. However, either the mic or the ALC889
1750 * makes the signal become a difference/sum signal instead of standard
1751 * stereo, which is annoying. So instead we flip this bit which makes the
1752 * codec replicate the sum signal to both channels, turning it into a
1753 * normal mono mic.
1754 */
1755/* DMIC_CONTROL? Init value = 0x0001 */
1756 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1757 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1758 { }
1759};
1760
ef8ef5fb 1761static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1762 /* Front mic only available on one ADC */
1763 {
1764 .num_items = 4,
1765 .items = {
1766 { "Mic", 0x0 },
1767 { "Line", 0x2 },
1768 { "CD", 0x4 },
1769 { "Front Mic", 0xb },
1770 },
1771 },
1772 {
1773 .num_items = 3,
1774 .items = {
1775 { "Mic", 0x0 },
1776 { "Line", 0x2 },
1777 { "CD", 0x4 },
1778 },
1779 }
1780};
1781
d2fd4b09
TV
1782static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1783 /* Interal mic only available on one ADC */
1784 {
684a8842 1785 .num_items = 5,
d2fd4b09
TV
1786 .items = {
1787 { "Ext Mic", 0x0 },
684a8842 1788 { "Line In", 0x2 },
d2fd4b09 1789 { "CD", 0x4 },
684a8842 1790 { "Input Mix", 0xa },
d2fd4b09
TV
1791 { "Int Mic", 0xb },
1792 },
1793 },
1794 {
684a8842 1795 .num_items = 4,
d2fd4b09
TV
1796 .items = {
1797 { "Ext Mic", 0x0 },
684a8842 1798 { "Line In", 0x2 },
d2fd4b09 1799 { "CD", 0x4 },
684a8842 1800 { "Input Mix", 0xa },
d2fd4b09
TV
1801 },
1802 }
1803};
1804
018df418
HM
1805static struct hda_input_mux alc889_capture_sources[3] = {
1806 /* Digital mic only available on first "ADC" */
1807 {
1808 .num_items = 5,
1809 .items = {
1810 { "Mic", 0x0 },
1811 { "Line", 0x2 },
1812 { "CD", 0x4 },
1813 { "Front Mic", 0xb },
1814 { "Input Mix", 0xa },
1815 },
1816 },
1817 {
1818 .num_items = 4,
1819 .items = {
1820 { "Mic", 0x0 },
1821 { "Line", 0x2 },
1822 { "CD", 0x4 },
1823 { "Input Mix", 0xa },
1824 },
1825 },
1826 {
1827 .num_items = 4,
1828 .items = {
1829 { "Mic", 0x0 },
1830 { "Line", 0x2 },
1831 { "CD", 0x4 },
1832 { "Input Mix", 0xa },
1833 },
1834 }
1835};
1836
ef8ef5fb 1837static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1838 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1840 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1841 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1842 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1843 HDA_OUTPUT),
1844 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1845 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1846 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1847 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1848 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1849 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1850 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1856 { } /* end */
1857};
1858
556eea9a
HM
1859static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1860 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1861 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1862 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1863 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1864 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1865 HDA_OUTPUT),
1866 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1867 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1868 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1869 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1870 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1872 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1874 { } /* end */
1875};
1876
1877
4f5d1706 1878static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 1879{
a9fd4f3f 1880 struct alc_spec *spec = codec->spec;
5b2d1eca 1881
a9fd4f3f
TI
1882 spec->autocfg.hp_pins[0] = 0x15;
1883 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
1884 spec->autocfg.speaker_pins[1] = 0x16;
1885 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
1886}
1887
4f5d1706 1888static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
1889{
1890 struct alc_spec *spec = codec->spec;
1891
1892 spec->autocfg.hp_pins[0] = 0x15;
1893 spec->autocfg.speaker_pins[0] = 0x14;
1894 spec->autocfg.speaker_pins[1] = 0x16;
1895 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
1896}
1897
4f5d1706 1898static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
1899{
1900 struct alc_spec *spec = codec->spec;
1901
1902 spec->autocfg.hp_pins[0] = 0x15;
1903 spec->autocfg.speaker_pins[0] = 0x14;
1904 spec->autocfg.speaker_pins[1] = 0x16;
1905 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
1906}
1907
1da177e4 1908/*
e9edcee0
TI
1909 * ALC880 3-stack model
1910 *
1911 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1912 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1913 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1914 */
1915
e9edcee0
TI
1916static hda_nid_t alc880_dac_nids[4] = {
1917 /* front, rear, clfe, rear_surr */
1918 0x02, 0x05, 0x04, 0x03
1919};
1920
1921static hda_nid_t alc880_adc_nids[3] = {
1922 /* ADC0-2 */
1923 0x07, 0x08, 0x09,
1924};
1925
1926/* The datasheet says the node 0x07 is connected from inputs,
1927 * but it shows zero connection in the real implementation on some devices.
df694daa 1928 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1929 */
e9edcee0
TI
1930static hda_nid_t alc880_adc_nids_alt[2] = {
1931 /* ADC1-2 */
1932 0x08, 0x09,
1933};
1934
1935#define ALC880_DIGOUT_NID 0x06
1936#define ALC880_DIGIN_NID 0x0a
1937
1938static struct hda_input_mux alc880_capture_source = {
1939 .num_items = 4,
1940 .items = {
1941 { "Mic", 0x0 },
1942 { "Front Mic", 0x3 },
1943 { "Line", 0x2 },
1944 { "CD", 0x4 },
1945 },
1946};
1947
1948/* channel source setting (2/6 channel selection for 3-stack) */
1949/* 2ch mode */
1950static struct hda_verb alc880_threestack_ch2_init[] = {
1951 /* set line-in to input, mute it */
1952 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1953 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1954 /* set mic-in to input vref 80%, mute it */
1955 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1956 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1957 { } /* end */
1958};
1959
1960/* 6ch mode */
1961static struct hda_verb alc880_threestack_ch6_init[] = {
1962 /* set line-in to output, unmute it */
1963 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1964 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1965 /* set mic-in to output, unmute it */
1966 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1967 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1968 { } /* end */
1969};
1970
d2a6d7dc 1971static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1972 { 2, alc880_threestack_ch2_init },
1973 { 6, alc880_threestack_ch6_init },
1974};
1975
c8b6bf9b 1976static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1977 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1978 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1979 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1980 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1981 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1982 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1983 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1984 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1994 {
1995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1996 .name = "Channel Mode",
df694daa
KY
1997 .info = alc_ch_mode_info,
1998 .get = alc_ch_mode_get,
1999 .put = alc_ch_mode_put,
e9edcee0
TI
2000 },
2001 { } /* end */
2002};
2003
2004/* capture mixer elements */
f9e336f6
TI
2005static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2006 struct snd_ctl_elem_info *uinfo)
2007{
2008 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2009 struct alc_spec *spec = codec->spec;
2010 int err;
1da177e4 2011
5a9e02e9 2012 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2013 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2014 HDA_INPUT);
2015 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2016 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2017 return err;
2018}
2019
2020static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2021 unsigned int size, unsigned int __user *tlv)
2022{
2023 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2024 struct alc_spec *spec = codec->spec;
2025 int err;
1da177e4 2026
5a9e02e9 2027 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2028 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2029 HDA_INPUT);
2030 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2031 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2032 return err;
2033}
2034
2035typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2036 struct snd_ctl_elem_value *ucontrol);
2037
2038static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2039 struct snd_ctl_elem_value *ucontrol,
2040 getput_call_t func)
2041{
2042 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2043 struct alc_spec *spec = codec->spec;
2044 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2045 int err;
2046
5a9e02e9 2047 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2048 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2049 3, 0, HDA_INPUT);
2050 err = func(kcontrol, ucontrol);
5a9e02e9 2051 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2052 return err;
2053}
2054
2055static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2056 struct snd_ctl_elem_value *ucontrol)
2057{
2058 return alc_cap_getput_caller(kcontrol, ucontrol,
2059 snd_hda_mixer_amp_volume_get);
2060}
2061
2062static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2063 struct snd_ctl_elem_value *ucontrol)
2064{
2065 return alc_cap_getput_caller(kcontrol, ucontrol,
2066 snd_hda_mixer_amp_volume_put);
2067}
2068
2069/* capture mixer elements */
2070#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2071
2072static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2073 struct snd_ctl_elem_value *ucontrol)
2074{
2075 return alc_cap_getput_caller(kcontrol, ucontrol,
2076 snd_hda_mixer_amp_switch_get);
2077}
2078
2079static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2080 struct snd_ctl_elem_value *ucontrol)
2081{
2082 return alc_cap_getput_caller(kcontrol, ucontrol,
2083 snd_hda_mixer_amp_switch_put);
2084}
2085
a23b688f 2086#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2087 { \
2088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2089 .name = "Capture Switch", \
2090 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2091 .count = num, \
2092 .info = alc_cap_sw_info, \
2093 .get = alc_cap_sw_get, \
2094 .put = alc_cap_sw_put, \
2095 }, \
2096 { \
2097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2098 .name = "Capture Volume", \
2099 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2100 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2101 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2102 .count = num, \
2103 .info = alc_cap_vol_info, \
2104 .get = alc_cap_vol_get, \
2105 .put = alc_cap_vol_put, \
2106 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2107 }
2108
2109#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2110 { \
2111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2112 /* .name = "Capture Source", */ \
2113 .name = "Input Source", \
2114 .count = num, \
2115 .info = alc_mux_enum_info, \
2116 .get = alc_mux_enum_get, \
2117 .put = alc_mux_enum_put, \
a23b688f
TI
2118 }
2119
2120#define DEFINE_CAPMIX(num) \
2121static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2122 _DEFINE_CAPMIX(num), \
2123 _DEFINE_CAPSRC(num), \
2124 { } /* end */ \
2125}
2126
2127#define DEFINE_CAPMIX_NOSRC(num) \
2128static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2129 _DEFINE_CAPMIX(num), \
2130 { } /* end */ \
f9e336f6
TI
2131}
2132
2133/* up to three ADCs */
2134DEFINE_CAPMIX(1);
2135DEFINE_CAPMIX(2);
2136DEFINE_CAPMIX(3);
a23b688f
TI
2137DEFINE_CAPMIX_NOSRC(1);
2138DEFINE_CAPMIX_NOSRC(2);
2139DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2140
2141/*
2142 * ALC880 5-stack model
2143 *
9c7f852e
TI
2144 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2145 * Side = 0x02 (0xd)
e9edcee0
TI
2146 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2147 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2148 */
2149
2150/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2151static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2152 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2153 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2154 { } /* end */
2155};
2156
e9edcee0
TI
2157/* channel source setting (6/8 channel selection for 5-stack) */
2158/* 6ch mode */
2159static struct hda_verb alc880_fivestack_ch6_init[] = {
2160 /* set line-in to input, mute it */
2161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2163 { } /* end */
2164};
2165
e9edcee0
TI
2166/* 8ch mode */
2167static struct hda_verb alc880_fivestack_ch8_init[] = {
2168 /* set line-in to output, unmute it */
2169 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2170 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2171 { } /* end */
2172};
2173
d2a6d7dc 2174static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2175 { 6, alc880_fivestack_ch6_init },
2176 { 8, alc880_fivestack_ch8_init },
2177};
2178
2179
2180/*
2181 * ALC880 6-stack model
2182 *
9c7f852e
TI
2183 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2184 * Side = 0x05 (0x0f)
e9edcee0
TI
2185 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2186 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2187 */
2188
2189static hda_nid_t alc880_6st_dac_nids[4] = {
2190 /* front, rear, clfe, rear_surr */
2191 0x02, 0x03, 0x04, 0x05
f12ab1e0 2192};
e9edcee0
TI
2193
2194static struct hda_input_mux alc880_6stack_capture_source = {
2195 .num_items = 4,
2196 .items = {
2197 { "Mic", 0x0 },
2198 { "Front Mic", 0x1 },
2199 { "Line", 0x2 },
2200 { "CD", 0x4 },
2201 },
2202};
2203
2204/* fixed 8-channels */
d2a6d7dc 2205static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2206 { 8, NULL },
2207};
2208
c8b6bf9b 2209static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2213 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2214 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2215 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2216 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2217 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2218 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2219 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2226 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2227 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2228 {
2229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2230 .name = "Channel Mode",
df694daa
KY
2231 .info = alc_ch_mode_info,
2232 .get = alc_ch_mode_get,
2233 .put = alc_ch_mode_put,
16ded525
TI
2234 },
2235 { } /* end */
2236};
2237
e9edcee0
TI
2238
2239/*
2240 * ALC880 W810 model
2241 *
2242 * W810 has rear IO for:
2243 * Front (DAC 02)
2244 * Surround (DAC 03)
2245 * Center/LFE (DAC 04)
2246 * Digital out (06)
2247 *
2248 * The system also has a pair of internal speakers, and a headphone jack.
2249 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2250 *
e9edcee0
TI
2251 * There is a variable resistor to control the speaker or headphone
2252 * volume. This is a hardware-only device without a software API.
2253 *
2254 * Plugging headphones in will disable the internal speakers. This is
2255 * implemented in hardware, not via the driver using jack sense. In
2256 * a similar fashion, plugging into the rear socket marked "front" will
2257 * disable both the speakers and headphones.
2258 *
2259 * For input, there's a microphone jack, and an "audio in" jack.
2260 * These may not do anything useful with this driver yet, because I
2261 * haven't setup any initialization verbs for these yet...
2262 */
2263
2264static hda_nid_t alc880_w810_dac_nids[3] = {
2265 /* front, rear/surround, clfe */
2266 0x02, 0x03, 0x04
16ded525
TI
2267};
2268
e9edcee0 2269/* fixed 6 channels */
d2a6d7dc 2270static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2271 { 6, NULL }
2272};
2273
2274/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2275static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2276 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2277 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2278 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2279 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2280 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2281 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2282 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2283 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2285 { } /* end */
2286};
2287
2288
2289/*
2290 * Z710V model
2291 *
2292 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2293 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2294 * Line = 0x1a
e9edcee0
TI
2295 */
2296
2297static hda_nid_t alc880_z71v_dac_nids[1] = {
2298 0x02
2299};
2300#define ALC880_Z71V_HP_DAC 0x03
2301
2302/* fixed 2 channels */
d2a6d7dc 2303static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2304 { 2, NULL }
2305};
2306
c8b6bf9b 2307static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2309 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2310 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2311 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2312 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2313 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2316 { } /* end */
2317};
2318
e9edcee0 2319
e9edcee0
TI
2320/*
2321 * ALC880 F1734 model
2322 *
2323 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2324 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2325 */
2326
2327static hda_nid_t alc880_f1734_dac_nids[1] = {
2328 0x03
2329};
2330#define ALC880_F1734_HP_DAC 0x02
2331
c8b6bf9b 2332static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2333 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2334 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2335 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2336 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2337 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2338 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2339 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2340 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2341 { } /* end */
2342};
2343
937b4160
TI
2344static struct hda_input_mux alc880_f1734_capture_source = {
2345 .num_items = 2,
2346 .items = {
2347 { "Mic", 0x1 },
2348 { "CD", 0x4 },
2349 },
2350};
2351
e9edcee0 2352
e9edcee0
TI
2353/*
2354 * ALC880 ASUS model
2355 *
2356 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2357 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2358 * Mic = 0x18, Line = 0x1a
2359 */
2360
2361#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2362#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2363
c8b6bf9b 2364static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2371 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2372 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2375 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2376 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2379 {
2380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2381 .name = "Channel Mode",
df694daa
KY
2382 .info = alc_ch_mode_info,
2383 .get = alc_ch_mode_get,
2384 .put = alc_ch_mode_put,
16ded525
TI
2385 },
2386 { } /* end */
2387};
e9edcee0 2388
e9edcee0
TI
2389/*
2390 * ALC880 ASUS W1V model
2391 *
2392 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2393 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2394 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2395 */
2396
2397/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2398static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2399 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2400 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2401 { } /* end */
2402};
2403
df694daa
KY
2404/* TCL S700 */
2405static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2406 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2407 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2409 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2410 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2413 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2414 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2415 { } /* end */
2416};
2417
ccc656ce
KY
2418/* Uniwill */
2419static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2420 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2421 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2422 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2423 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2424 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2425 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2426 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2427 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2428 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2429 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2430 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2431 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2436 {
2437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2438 .name = "Channel Mode",
2439 .info = alc_ch_mode_info,
2440 .get = alc_ch_mode_get,
2441 .put = alc_ch_mode_put,
2442 },
2443 { } /* end */
2444};
2445
2cf9f0fc
TD
2446static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2449 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2450 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2451 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2452 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2453 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2454 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2455 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2456 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2457 { } /* end */
2458};
2459
ccc656ce 2460static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2461 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2462 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2463 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2464 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2467 { } /* end */
2468};
2469
2134ea4f
TI
2470/*
2471 * virtual master controls
2472 */
2473
2474/*
2475 * slave controls for virtual master
2476 */
2477static const char *alc_slave_vols[] = {
2478 "Front Playback Volume",
2479 "Surround Playback Volume",
2480 "Center Playback Volume",
2481 "LFE Playback Volume",
2482 "Side Playback Volume",
2483 "Headphone Playback Volume",
2484 "Speaker Playback Volume",
2485 "Mono Playback Volume",
2134ea4f 2486 "Line-Out Playback Volume",
26f5df26 2487 "PCM Playback Volume",
2134ea4f
TI
2488 NULL,
2489};
2490
2491static const char *alc_slave_sws[] = {
2492 "Front Playback Switch",
2493 "Surround Playback Switch",
2494 "Center Playback Switch",
2495 "LFE Playback Switch",
2496 "Side Playback Switch",
2497 "Headphone Playback Switch",
2498 "Speaker Playback Switch",
2499 "Mono Playback Switch",
edb54a55 2500 "IEC958 Playback Switch",
23033b2b
TI
2501 "Line-Out Playback Switch",
2502 "PCM Playback Switch",
2134ea4f
TI
2503 NULL,
2504};
2505
1da177e4 2506/*
e9edcee0 2507 * build control elements
1da177e4 2508 */
603c4019 2509
5b0cb1d8
JK
2510#define NID_MAPPING (-1)
2511
2512#define SUBDEV_SPEAKER_ (0 << 6)
2513#define SUBDEV_HP_ (1 << 6)
2514#define SUBDEV_LINE_ (2 << 6)
2515#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2516#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2517#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2518
603c4019
TI
2519static void alc_free_kctls(struct hda_codec *codec);
2520
67d634c0 2521#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2522/* additional beep mixers; the actual parameters are overwritten at build */
2523static struct snd_kcontrol_new alc_beep_mixer[] = {
2524 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2525 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2526 { } /* end */
2527};
67d634c0 2528#endif
45bdd1c1 2529
1da177e4
LT
2530static int alc_build_controls(struct hda_codec *codec)
2531{
2532 struct alc_spec *spec = codec->spec;
5b0cb1d8
JK
2533 struct snd_kcontrol *kctl;
2534 struct snd_kcontrol_new *knew;
2535 int i, j, err;
2536 unsigned int u;
2537 hda_nid_t nid;
1da177e4
LT
2538
2539 for (i = 0; i < spec->num_mixers; i++) {
2540 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2541 if (err < 0)
2542 return err;
2543 }
f9e336f6
TI
2544 if (spec->cap_mixer) {
2545 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2546 if (err < 0)
2547 return err;
2548 }
1da177e4 2549 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2550 err = snd_hda_create_spdif_out_ctls(codec,
2551 spec->multiout.dig_out_nid);
1da177e4
LT
2552 if (err < 0)
2553 return err;
e64f14f4
TI
2554 if (!spec->no_analog) {
2555 err = snd_hda_create_spdif_share_sw(codec,
2556 &spec->multiout);
2557 if (err < 0)
2558 return err;
2559 spec->multiout.share_spdif = 1;
2560 }
1da177e4
LT
2561 }
2562 if (spec->dig_in_nid) {
2563 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2564 if (err < 0)
2565 return err;
2566 }
2134ea4f 2567
67d634c0 2568#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2569 /* create beep controls if needed */
2570 if (spec->beep_amp) {
2571 struct snd_kcontrol_new *knew;
2572 for (knew = alc_beep_mixer; knew->name; knew++) {
2573 struct snd_kcontrol *kctl;
2574 kctl = snd_ctl_new1(knew, codec);
2575 if (!kctl)
2576 return -ENOMEM;
2577 kctl->private_value = spec->beep_amp;
5e26dfd0 2578 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2579 if (err < 0)
2580 return err;
2581 }
2582 }
67d634c0 2583#endif
45bdd1c1 2584
2134ea4f 2585 /* if we have no master control, let's create it */
e64f14f4
TI
2586 if (!spec->no_analog &&
2587 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2588 unsigned int vmaster_tlv[4];
2134ea4f 2589 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2590 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2591 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2592 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2593 if (err < 0)
2594 return err;
2595 }
e64f14f4
TI
2596 if (!spec->no_analog &&
2597 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2598 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2599 NULL, alc_slave_sws);
2600 if (err < 0)
2601 return err;
2602 }
2603
5b0cb1d8
JK
2604 /* assign Capture Source enums to NID */
2605 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2606 if (!kctl)
2607 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2608 for (i = 0; kctl && i < kctl->count; i++) {
d1409ae4
TI
2609 hda_nid_t *nids = spec->capsrc_nids;
2610 if (!nids)
2611 nids = spec->adc_nids;
21949f00 2612 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
5b0cb1d8
JK
2613 if (err < 0)
2614 return err;
2615 }
2616 if (spec->cap_mixer) {
2617 const char *kname = kctl ? kctl->id.name : NULL;
2618 for (knew = spec->cap_mixer; knew->name; knew++) {
2619 if (kname && strcmp(knew->name, kname) == 0)
2620 continue;
2621 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2622 for (i = 0; kctl && i < kctl->count; i++) {
2623 err = snd_hda_add_nid(codec, kctl, i,
2624 spec->adc_nids[i]);
2625 if (err < 0)
2626 return err;
2627 }
2628 }
2629 }
2630
2631 /* other nid->control mapping */
2632 for (i = 0; i < spec->num_mixers; i++) {
2633 for (knew = spec->mixers[i]; knew->name; knew++) {
2634 if (knew->iface != NID_MAPPING)
2635 continue;
2636 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2637 if (kctl == NULL)
2638 continue;
2639 u = knew->subdevice;
2640 for (j = 0; j < 4; j++, u >>= 8) {
2641 nid = u & 0x3f;
2642 if (nid == 0)
2643 continue;
2644 switch (u & 0xc0) {
2645 case SUBDEV_SPEAKER_:
2646 nid = spec->autocfg.speaker_pins[nid];
2647 break;
2648 case SUBDEV_LINE_:
2649 nid = spec->autocfg.line_out_pins[nid];
2650 break;
2651 case SUBDEV_HP_:
2652 nid = spec->autocfg.hp_pins[nid];
2653 break;
2654 default:
2655 continue;
2656 }
2657 err = snd_hda_add_nid(codec, kctl, 0, nid);
2658 if (err < 0)
2659 return err;
2660 }
2661 u = knew->private_value;
2662 for (j = 0; j < 4; j++, u >>= 8) {
2663 nid = u & 0xff;
2664 if (nid == 0)
2665 continue;
2666 err = snd_hda_add_nid(codec, kctl, 0, nid);
2667 if (err < 0)
2668 return err;
2669 }
2670 }
2671 }
bae84e70
TI
2672
2673 alc_free_kctls(codec); /* no longer needed */
2674
1da177e4
LT
2675 return 0;
2676}
2677
e9edcee0 2678
1da177e4
LT
2679/*
2680 * initialize the codec volumes, etc
2681 */
2682
e9edcee0
TI
2683/*
2684 * generic initialization of ADC, input mixers and output mixers
2685 */
2686static struct hda_verb alc880_volume_init_verbs[] = {
2687 /*
2688 * Unmute ADC0-2 and set the default input to mic-in
2689 */
71fe7b82 2690 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2692 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2693 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2694 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2695 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2696
e9edcee0
TI
2697 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2698 * mixer widget
9c7f852e
TI
2699 * Note: PASD motherboards uses the Line In 2 as the input for front
2700 * panel mic (mic 2)
1da177e4 2701 */
e9edcee0 2702 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2703 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2710
e9edcee0
TI
2711 /*
2712 * Set up output mixers (0x0c - 0x0f)
1da177e4 2713 */
e9edcee0
TI
2714 /* set vol=0 to output mixers */
2715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2716 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2718 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2719 /* set up input amps for analog loopback */
2720 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2724 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2726 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2727 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2728 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2729
2730 { }
2731};
2732
e9edcee0
TI
2733/*
2734 * 3-stack pin configuration:
2735 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2736 */
2737static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2738 /*
2739 * preset connection lists of input pins
2740 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2741 */
2742 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2743 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2744 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2745
2746 /*
2747 * Set pin mode and muting
2748 */
2749 /* set front pin widgets 0x14 for output */
05acb863 2750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2751 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2752 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2755 /* Mic2 (as headphone out) for HP output */
2756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2758 /* Line In pin widget for input */
05acb863 2759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2761 /* Line2 (as front mic) pin widget for input and vref at 80% */
2762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2763 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2764 /* CD pin widget for input */
05acb863 2765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2766
e9edcee0
TI
2767 { }
2768};
1da177e4 2769
e9edcee0
TI
2770/*
2771 * 5-stack pin configuration:
2772 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2773 * line-in/side = 0x1a, f-mic = 0x1b
2774 */
2775static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2776 /*
2777 * preset connection lists of input pins
2778 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2779 */
e9edcee0
TI
2780 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2781 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2782
e9edcee0
TI
2783 /*
2784 * Set pin mode and muting
1da177e4 2785 */
e9edcee0
TI
2786 /* set pin widgets 0x14-0x17 for output */
2787 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2789 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2790 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2791 /* unmute pins for output (no gain on this amp) */
2792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2794 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2795 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796
2797 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2798 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2799 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2800 /* Mic2 (as headphone out) for HP output */
2801 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2802 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2803 /* Line In pin widget for input */
2804 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2806 /* Line2 (as front mic) pin widget for input and vref at 80% */
2807 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2808 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2809 /* CD pin widget for input */
2810 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2811
2812 { }
2813};
2814
e9edcee0
TI
2815/*
2816 * W810 pin configuration:
2817 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2818 */
2819static struct hda_verb alc880_pin_w810_init_verbs[] = {
2820 /* hphone/speaker input selector: front DAC */
2821 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2822
05acb863 2823 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2827 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2828 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2829
e9edcee0 2830 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2831 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2832
1da177e4
LT
2833 { }
2834};
2835
e9edcee0
TI
2836/*
2837 * Z71V pin configuration:
2838 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2839 */
2840static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2845
16ded525 2846 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2847 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2848 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2849 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2850
2851 { }
2852};
2853
e9edcee0
TI
2854/*
2855 * 6-stack pin configuration:
9c7f852e
TI
2856 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2857 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2858 */
2859static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2860 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2861
16ded525 2862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2866 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2867 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2868 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2870
16ded525 2871 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2873 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2874 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2878 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2879 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2880
e9edcee0
TI
2881 { }
2882};
2883
ccc656ce
KY
2884/*
2885 * Uniwill pin configuration:
2886 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2887 * line = 0x1a
2888 */
2889static struct hda_verb alc880_uniwill_init_verbs[] = {
2890 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2891
2892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2895 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2896 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2897 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2898 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2899 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2900 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2901 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2902 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2903 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2905 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2906
2907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2909 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2910 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2912 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2913 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2914 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2915 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2916
2917 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2918 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2919
2920 { }
2921};
2922
2923/*
2924* Uniwill P53
ea1fb29a 2925* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2926 */
2927static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2928 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2929
2930 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2931 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2933 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2935 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2938 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2939 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2940 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2941 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2942
2943 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2944 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2946 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2947 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2948 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2949
2950 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2951 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2952
2953 { }
2954};
2955
2cf9f0fc
TD
2956static struct hda_verb alc880_beep_init_verbs[] = {
2957 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2958 { }
2959};
2960
458a4fab
TI
2961/* auto-toggle front mic */
2962static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2963{
2964 unsigned int present;
2965 unsigned char bits;
ccc656ce 2966
864f92be 2967 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
2968 bits = present ? HDA_AMP_MUTE : 0;
2969 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2970}
2971
4f5d1706 2972static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 2973{
a9fd4f3f
TI
2974 struct alc_spec *spec = codec->spec;
2975
2976 spec->autocfg.hp_pins[0] = 0x14;
2977 spec->autocfg.speaker_pins[0] = 0x15;
2978 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
2979}
2980
2981static void alc880_uniwill_init_hook(struct hda_codec *codec)
2982{
a9fd4f3f 2983 alc_automute_amp(codec);
458a4fab 2984 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2985}
2986
2987static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2988 unsigned int res)
2989{
2990 /* Looks like the unsol event is incompatible with the standard
2991 * definition. 4bit tag is placed at 28 bit!
2992 */
458a4fab 2993 switch (res >> 28) {
458a4fab
TI
2994 case ALC880_MIC_EVENT:
2995 alc880_uniwill_mic_automute(codec);
2996 break;
a9fd4f3f
TI
2997 default:
2998 alc_automute_amp_unsol_event(codec, res);
2999 break;
458a4fab 3000 }
ccc656ce
KY
3001}
3002
4f5d1706 3003static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3004{
a9fd4f3f 3005 struct alc_spec *spec = codec->spec;
ccc656ce 3006
a9fd4f3f
TI
3007 spec->autocfg.hp_pins[0] = 0x14;
3008 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3009}
3010
3011static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3012{
3013 unsigned int present;
ea1fb29a 3014
ccc656ce 3015 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3016 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3017 present &= HDA_AMP_VOLMASK;
3018 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3019 HDA_AMP_VOLMASK, present);
3020 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3021 HDA_AMP_VOLMASK, present);
ccc656ce 3022}
47fd830a 3023
ccc656ce
KY
3024static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3025 unsigned int res)
3026{
3027 /* Looks like the unsol event is incompatible with the standard
3028 * definition. 4bit tag is placed at 28 bit!
3029 */
f12ab1e0 3030 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3031 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3032 else
3033 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3034}
3035
e9edcee0
TI
3036/*
3037 * F1734 pin configuration:
3038 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3039 */
3040static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3041 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3042 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3043 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3044 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3045 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3046
e9edcee0 3047 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3048 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3049 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3050 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3051
e9edcee0
TI
3052 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3053 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3054 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3055 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3056 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3057 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3058 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3059 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3060 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3061
937b4160
TI
3062 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3063 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3064
dfc0ff62
TI
3065 { }
3066};
3067
e9edcee0
TI
3068/*
3069 * ASUS pin configuration:
3070 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3071 */
3072static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3073 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3074 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3075 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3076 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3077
3078 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3079 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3080 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3081 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3082 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3083 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3084 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3086
3087 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3089 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3090 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3091 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3093 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3094 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3095 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3096
e9edcee0
TI
3097 { }
3098};
16ded525 3099
e9edcee0 3100/* Enable GPIO mask and set output */
bc9f98a9
KY
3101#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3102#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3103#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3104
3105/* Clevo m520g init */
3106static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3107 /* headphone output */
3108 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3109 /* line-out */
3110 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3111 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3112 /* Line-in */
3113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3115 /* CD */
3116 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3117 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3118 /* Mic1 (rear panel) */
3119 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3120 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3121 /* Mic2 (front panel) */
3122 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3123 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3124 /* headphone */
3125 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3126 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3127 /* change to EAPD mode */
3128 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3129 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3130
3131 { }
16ded525
TI
3132};
3133
df694daa 3134static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3135 /* change to EAPD mode */
3136 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3137 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3138
df694daa
KY
3139 /* Headphone output */
3140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3141 /* Front output*/
3142 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3143 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3144
3145 /* Line In pin widget for input */
3146 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3147 /* CD pin widget for input */
3148 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3149 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3151
3152 /* change to EAPD mode */
3153 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3154 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3155
3156 { }
3157};
16ded525 3158
e9edcee0 3159/*
ae6b813a
TI
3160 * LG m1 express dual
3161 *
3162 * Pin assignment:
3163 * Rear Line-In/Out (blue): 0x14
3164 * Build-in Mic-In: 0x15
3165 * Speaker-out: 0x17
3166 * HP-Out (green): 0x1b
3167 * Mic-In/Out (red): 0x19
3168 * SPDIF-Out: 0x1e
3169 */
3170
3171/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3172static hda_nid_t alc880_lg_dac_nids[3] = {
3173 0x05, 0x02, 0x03
3174};
3175
3176/* seems analog CD is not working */
3177static struct hda_input_mux alc880_lg_capture_source = {
3178 .num_items = 3,
3179 .items = {
3180 { "Mic", 0x1 },
3181 { "Line", 0x5 },
3182 { "Internal Mic", 0x6 },
3183 },
3184};
3185
3186/* 2,4,6 channel modes */
3187static struct hda_verb alc880_lg_ch2_init[] = {
3188 /* set line-in and mic-in to input */
3189 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3190 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3191 { }
3192};
3193
3194static struct hda_verb alc880_lg_ch4_init[] = {
3195 /* set line-in to out and mic-in to input */
3196 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3197 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3198 { }
3199};
3200
3201static struct hda_verb alc880_lg_ch6_init[] = {
3202 /* set line-in and mic-in to output */
3203 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3204 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3205 { }
3206};
3207
3208static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3209 { 2, alc880_lg_ch2_init },
3210 { 4, alc880_lg_ch4_init },
3211 { 6, alc880_lg_ch6_init },
3212};
3213
3214static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3216 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3217 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3218 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3219 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3220 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3221 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3222 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3224 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3225 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3226 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3227 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3228 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3229 {
3230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3231 .name = "Channel Mode",
3232 .info = alc_ch_mode_info,
3233 .get = alc_ch_mode_get,
3234 .put = alc_ch_mode_put,
3235 },
3236 { } /* end */
3237};
3238
3239static struct hda_verb alc880_lg_init_verbs[] = {
3240 /* set capture source to mic-in */
3241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3244 /* mute all amp mixer inputs */
3245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3248 /* line-in to input */
3249 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3250 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3251 /* built-in mic */
3252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3254 /* speaker-out */
3255 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3256 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3257 /* mic-in to input */
3258 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3259 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3260 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3261 /* HP-out */
3262 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3263 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3264 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3265 /* jack sense */
a9fd4f3f 3266 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3267 { }
3268};
3269
3270/* toggle speaker-output according to the hp-jack state */
4f5d1706 3271static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3272{
a9fd4f3f 3273 struct alc_spec *spec = codec->spec;
ae6b813a 3274
a9fd4f3f
TI
3275 spec->autocfg.hp_pins[0] = 0x1b;
3276 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3277}
3278
d681518a
TI
3279/*
3280 * LG LW20
3281 *
3282 * Pin assignment:
3283 * Speaker-out: 0x14
3284 * Mic-In: 0x18
e4f41da9
CM
3285 * Built-in Mic-In: 0x19
3286 * Line-In: 0x1b
3287 * HP-Out: 0x1a
d681518a
TI
3288 * SPDIF-Out: 0x1e
3289 */
3290
d681518a 3291static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3292 .num_items = 3,
d681518a
TI
3293 .items = {
3294 { "Mic", 0x0 },
3295 { "Internal Mic", 0x1 },
e4f41da9 3296 { "Line In", 0x2 },
d681518a
TI
3297 },
3298};
3299
0a8c5da3
CM
3300#define alc880_lg_lw_modes alc880_threestack_modes
3301
d681518a 3302static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3303 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3304 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3305 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3306 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3307 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3308 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3309 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3310 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3314 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3315 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3316 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3317 {
3318 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3319 .name = "Channel Mode",
3320 .info = alc_ch_mode_info,
3321 .get = alc_ch_mode_get,
3322 .put = alc_ch_mode_put,
3323 },
d681518a
TI
3324 { } /* end */
3325};
3326
3327static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3328 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3329 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3330 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3331
d681518a
TI
3332 /* set capture source to mic-in */
3333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3334 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3335 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3337 /* speaker-out */
3338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3340 /* HP-out */
d681518a
TI
3341 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3342 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3343 /* mic-in to input */
3344 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3345 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3346 /* built-in mic */
3347 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3348 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3349 /* jack sense */
a9fd4f3f 3350 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3351 { }
3352};
3353
3354/* toggle speaker-output according to the hp-jack state */
4f5d1706 3355static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3356{
a9fd4f3f 3357 struct alc_spec *spec = codec->spec;
d681518a 3358
a9fd4f3f
TI
3359 spec->autocfg.hp_pins[0] = 0x1b;
3360 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3361}
3362
df99cd33
TI
3363static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3364 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3365 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3366 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3367 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3368 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3369 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3370 { } /* end */
3371};
3372
3373static struct hda_input_mux alc880_medion_rim_capture_source = {
3374 .num_items = 2,
3375 .items = {
3376 { "Mic", 0x0 },
3377 { "Internal Mic", 0x1 },
3378 },
3379};
3380
3381static struct hda_verb alc880_medion_rim_init_verbs[] = {
3382 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3383
3384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3385 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3386
3387 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3388 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3389 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3390 /* Mic2 (as headphone out) for HP output */
3391 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3392 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3393 /* Internal Speaker */
3394 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3395 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3396
3397 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3398 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3399
3400 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3401 { }
3402};
3403
3404/* toggle speaker-output according to the hp-jack state */
3405static void alc880_medion_rim_automute(struct hda_codec *codec)
3406{
a9fd4f3f
TI
3407 struct alc_spec *spec = codec->spec;
3408 alc_automute_amp(codec);
3409 /* toggle EAPD */
3410 if (spec->jack_present)
df99cd33
TI
3411 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3412 else
3413 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3414}
3415
3416static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3417 unsigned int res)
3418{
3419 /* Looks like the unsol event is incompatible with the standard
3420 * definition. 4bit tag is placed at 28 bit!
3421 */
3422 if ((res >> 28) == ALC880_HP_EVENT)
3423 alc880_medion_rim_automute(codec);
3424}
3425
4f5d1706 3426static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3427{
3428 struct alc_spec *spec = codec->spec;
3429
3430 spec->autocfg.hp_pins[0] = 0x14;
3431 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3432}
3433
cb53c626
TI
3434#ifdef CONFIG_SND_HDA_POWER_SAVE
3435static struct hda_amp_list alc880_loopbacks[] = {
3436 { 0x0b, HDA_INPUT, 0 },
3437 { 0x0b, HDA_INPUT, 1 },
3438 { 0x0b, HDA_INPUT, 2 },
3439 { 0x0b, HDA_INPUT, 3 },
3440 { 0x0b, HDA_INPUT, 4 },
3441 { } /* end */
3442};
3443
3444static struct hda_amp_list alc880_lg_loopbacks[] = {
3445 { 0x0b, HDA_INPUT, 1 },
3446 { 0x0b, HDA_INPUT, 6 },
3447 { 0x0b, HDA_INPUT, 7 },
3448 { } /* end */
3449};
3450#endif
3451
ae6b813a
TI
3452/*
3453 * Common callbacks
e9edcee0
TI
3454 */
3455
1da177e4
LT
3456static int alc_init(struct hda_codec *codec)
3457{
3458 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3459 unsigned int i;
3460
2c3bf9ab 3461 alc_fix_pll(codec);
4a79ba34 3462 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3463
e9edcee0
TI
3464 for (i = 0; i < spec->num_init_verbs; i++)
3465 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3466
3467 if (spec->init_hook)
3468 spec->init_hook(codec);
3469
ad35879a
TI
3470#ifdef CONFIG_SND_HDA_POWER_SAVE
3471 if (codec->patch_ops.check_power_status)
3472 codec->patch_ops.check_power_status(codec, 0x01);
3473#endif
1da177e4
LT
3474 return 0;
3475}
3476
ae6b813a
TI
3477static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3478{
3479 struct alc_spec *spec = codec->spec;
3480
3481 if (spec->unsol_event)
3482 spec->unsol_event(codec, res);
3483}
3484
cb53c626
TI
3485#ifdef CONFIG_SND_HDA_POWER_SAVE
3486static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3487{
3488 struct alc_spec *spec = codec->spec;
3489 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3490}
3491#endif
3492
1da177e4
LT
3493/*
3494 * Analog playback callbacks
3495 */
3496static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3497 struct hda_codec *codec,
c8b6bf9b 3498 struct snd_pcm_substream *substream)
1da177e4
LT
3499{
3500 struct alc_spec *spec = codec->spec;
9a08160b
TI
3501 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3502 hinfo);
1da177e4
LT
3503}
3504
3505static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3506 struct hda_codec *codec,
3507 unsigned int stream_tag,
3508 unsigned int format,
c8b6bf9b 3509 struct snd_pcm_substream *substream)
1da177e4
LT
3510{
3511 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3512 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3513 stream_tag, format, substream);
1da177e4
LT
3514}
3515
3516static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3517 struct hda_codec *codec,
c8b6bf9b 3518 struct snd_pcm_substream *substream)
1da177e4
LT
3519{
3520 struct alc_spec *spec = codec->spec;
3521 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3522}
3523
3524/*
3525 * Digital out
3526 */
3527static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3528 struct hda_codec *codec,
c8b6bf9b 3529 struct snd_pcm_substream *substream)
1da177e4
LT
3530{
3531 struct alc_spec *spec = codec->spec;
3532 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3533}
3534
6b97eb45
TI
3535static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3536 struct hda_codec *codec,
3537 unsigned int stream_tag,
3538 unsigned int format,
3539 struct snd_pcm_substream *substream)
3540{
3541 struct alc_spec *spec = codec->spec;
3542 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3543 stream_tag, format, substream);
3544}
3545
9b5f12e5
TI
3546static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3547 struct hda_codec *codec,
3548 struct snd_pcm_substream *substream)
3549{
3550 struct alc_spec *spec = codec->spec;
3551 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3552}
3553
1da177e4
LT
3554static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3555 struct hda_codec *codec,
c8b6bf9b 3556 struct snd_pcm_substream *substream)
1da177e4
LT
3557{
3558 struct alc_spec *spec = codec->spec;
3559 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3560}
3561
3562/*
3563 * Analog capture
3564 */
6330079f 3565static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3566 struct hda_codec *codec,
3567 unsigned int stream_tag,
3568 unsigned int format,
c8b6bf9b 3569 struct snd_pcm_substream *substream)
1da177e4
LT
3570{
3571 struct alc_spec *spec = codec->spec;
3572
6330079f 3573 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3574 stream_tag, 0, format);
3575 return 0;
3576}
3577
6330079f 3578static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3579 struct hda_codec *codec,
c8b6bf9b 3580 struct snd_pcm_substream *substream)
1da177e4
LT
3581{
3582 struct alc_spec *spec = codec->spec;
3583
888afa15
TI
3584 snd_hda_codec_cleanup_stream(codec,
3585 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3586 return 0;
3587}
3588
3589
3590/*
3591 */
3592static struct hda_pcm_stream alc880_pcm_analog_playback = {
3593 .substreams = 1,
3594 .channels_min = 2,
3595 .channels_max = 8,
e9edcee0 3596 /* NID is set in alc_build_pcms */
1da177e4
LT
3597 .ops = {
3598 .open = alc880_playback_pcm_open,
3599 .prepare = alc880_playback_pcm_prepare,
3600 .cleanup = alc880_playback_pcm_cleanup
3601 },
3602};
3603
3604static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3605 .substreams = 1,
3606 .channels_min = 2,
3607 .channels_max = 2,
3608 /* NID is set in alc_build_pcms */
3609};
3610
3611static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3612 .substreams = 1,
3613 .channels_min = 2,
3614 .channels_max = 2,
3615 /* NID is set in alc_build_pcms */
3616};
3617
3618static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3619 .substreams = 2, /* can be overridden */
1da177e4
LT
3620 .channels_min = 2,
3621 .channels_max = 2,
e9edcee0 3622 /* NID is set in alc_build_pcms */
1da177e4 3623 .ops = {
6330079f
TI
3624 .prepare = alc880_alt_capture_pcm_prepare,
3625 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3626 },
3627};
3628
3629static struct hda_pcm_stream alc880_pcm_digital_playback = {
3630 .substreams = 1,
3631 .channels_min = 2,
3632 .channels_max = 2,
3633 /* NID is set in alc_build_pcms */
3634 .ops = {
3635 .open = alc880_dig_playback_pcm_open,
6b97eb45 3636 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3637 .prepare = alc880_dig_playback_pcm_prepare,
3638 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3639 },
3640};
3641
3642static struct hda_pcm_stream alc880_pcm_digital_capture = {
3643 .substreams = 1,
3644 .channels_min = 2,
3645 .channels_max = 2,
3646 /* NID is set in alc_build_pcms */
3647};
3648
4c5186ed 3649/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3650static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3651 .substreams = 0,
3652 .channels_min = 0,
3653 .channels_max = 0,
3654};
3655
1da177e4
LT
3656static int alc_build_pcms(struct hda_codec *codec)
3657{
3658 struct alc_spec *spec = codec->spec;
3659 struct hda_pcm *info = spec->pcm_rec;
3660 int i;
3661
3662 codec->num_pcms = 1;
3663 codec->pcm_info = info;
3664
e64f14f4
TI
3665 if (spec->no_analog)
3666 goto skip_analog;
3667
812a2cca
TI
3668 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3669 "%s Analog", codec->chip_name);
1da177e4 3670 info->name = spec->stream_name_analog;
274693f3 3671
4a471b7d 3672 if (spec->stream_analog_playback) {
da3cec35
TI
3673 if (snd_BUG_ON(!spec->multiout.dac_nids))
3674 return -EINVAL;
4a471b7d
TI
3675 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3676 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3677 }
3678 if (spec->stream_analog_capture) {
da3cec35
TI
3679 if (snd_BUG_ON(!spec->adc_nids))
3680 return -EINVAL;
4a471b7d
TI
3681 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3682 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3683 }
3684
3685 if (spec->channel_mode) {
3686 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3687 for (i = 0; i < spec->num_channel_mode; i++) {
3688 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3689 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3690 }
1da177e4
LT
3691 }
3692 }
3693
e64f14f4 3694 skip_analog:
e08a007d 3695 /* SPDIF for stream index #1 */
1da177e4 3696 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3697 snprintf(spec->stream_name_digital,
3698 sizeof(spec->stream_name_digital),
3699 "%s Digital", codec->chip_name);
e08a007d 3700 codec->num_pcms = 2;
b25c9da1 3701 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3702 info = spec->pcm_rec + 1;
1da177e4 3703 info->name = spec->stream_name_digital;
8c441982
TI
3704 if (spec->dig_out_type)
3705 info->pcm_type = spec->dig_out_type;
3706 else
3707 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3708 if (spec->multiout.dig_out_nid &&
3709 spec->stream_digital_playback) {
1da177e4
LT
3710 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3711 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3712 }
4a471b7d
TI
3713 if (spec->dig_in_nid &&
3714 spec->stream_digital_capture) {
1da177e4
LT
3715 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3716 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3717 }
963f803f
TI
3718 /* FIXME: do we need this for all Realtek codec models? */
3719 codec->spdif_status_reset = 1;
1da177e4
LT
3720 }
3721
e64f14f4
TI
3722 if (spec->no_analog)
3723 return 0;
3724
e08a007d
TI
3725 /* If the use of more than one ADC is requested for the current
3726 * model, configure a second analog capture-only PCM.
3727 */
3728 /* Additional Analaog capture for index #2 */
6330079f
TI
3729 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3730 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3731 codec->num_pcms = 3;
c06134d7 3732 info = spec->pcm_rec + 2;
e08a007d 3733 info->name = spec->stream_name_analog;
6330079f
TI
3734 if (spec->alt_dac_nid) {
3735 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3736 *spec->stream_analog_alt_playback;
3737 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3738 spec->alt_dac_nid;
3739 } else {
3740 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3741 alc_pcm_null_stream;
3742 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3743 }
3744 if (spec->num_adc_nids > 1) {
3745 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3746 *spec->stream_analog_alt_capture;
3747 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3748 spec->adc_nids[1];
3749 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3750 spec->num_adc_nids - 1;
3751 } else {
3752 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3753 alc_pcm_null_stream;
3754 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3755 }
3756 }
3757
1da177e4
LT
3758 return 0;
3759}
3760
a4e09aa3
TI
3761static inline void alc_shutup(struct hda_codec *codec)
3762{
3763 snd_hda_shutup_pins(codec);
3764}
3765
603c4019
TI
3766static void alc_free_kctls(struct hda_codec *codec)
3767{
3768 struct alc_spec *spec = codec->spec;
3769
3770 if (spec->kctls.list) {
3771 struct snd_kcontrol_new *kctl = spec->kctls.list;
3772 int i;
3773 for (i = 0; i < spec->kctls.used; i++)
3774 kfree(kctl[i].name);
3775 }
3776 snd_array_free(&spec->kctls);
3777}
3778
1da177e4
LT
3779static void alc_free(struct hda_codec *codec)
3780{
e9edcee0 3781 struct alc_spec *spec = codec->spec;
e9edcee0 3782
f12ab1e0 3783 if (!spec)
e9edcee0
TI
3784 return;
3785
a4e09aa3 3786 alc_shutup(codec);
603c4019 3787 alc_free_kctls(codec);
e9edcee0 3788 kfree(spec);
680cd536 3789 snd_hda_detach_beep_device(codec);
1da177e4
LT
3790}
3791
f5de24b0 3792#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3793static void alc_power_eapd(struct hda_codec *codec)
3794{
3795 /* We currently only handle front, HP */
3796 switch (codec->vendor_id) {
3797 case 0x10ec0260:
9e4c8496
TI
3798 set_eapd(codec, 0x0f, 0);
3799 set_eapd(codec, 0x10, 0);
c97259df
DC
3800 break;
3801 case 0x10ec0262:
3802 case 0x10ec0267:
3803 case 0x10ec0268:
3804 case 0x10ec0269:
9e4c8496 3805 case 0x10ec0270:
c97259df
DC
3806 case 0x10ec0272:
3807 case 0x10ec0660:
3808 case 0x10ec0662:
3809 case 0x10ec0663:
3810 case 0x10ec0862:
3811 case 0x10ec0889:
9e4c8496
TI
3812 set_eapd(codec, 0x14, 0);
3813 set_eapd(codec, 0x15, 0);
c97259df
DC
3814 break;
3815 }
3816}
3817
f5de24b0
HM
3818static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3819{
3820 struct alc_spec *spec = codec->spec;
a4e09aa3 3821 alc_shutup(codec);
f5de24b0 3822 if (spec && spec->power_hook)
c97259df 3823 spec->power_hook(codec);
f5de24b0
HM
3824 return 0;
3825}
3826#endif
3827
e044c39a 3828#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3829static int alc_resume(struct hda_codec *codec)
3830{
e044c39a
TI
3831 codec->patch_ops.init(codec);
3832 snd_hda_codec_resume_amp(codec);
3833 snd_hda_codec_resume_cache(codec);
ad35879a
TI
3834#ifdef CONFIG_SND_HDA_POWER_SAVE
3835 if (codec->patch_ops.check_power_status)
3836 codec->patch_ops.check_power_status(codec, 0x01);
3837#endif
e044c39a
TI
3838 return 0;
3839}
e044c39a
TI
3840#endif
3841
1da177e4
LT
3842/*
3843 */
3844static struct hda_codec_ops alc_patch_ops = {
3845 .build_controls = alc_build_controls,
3846 .build_pcms = alc_build_pcms,
3847 .init = alc_init,
3848 .free = alc_free,
ae6b813a 3849 .unsol_event = alc_unsol_event,
e044c39a
TI
3850#ifdef SND_HDA_NEEDS_RESUME
3851 .resume = alc_resume,
3852#endif
cb53c626 3853#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 3854 .suspend = alc_suspend,
cb53c626
TI
3855 .check_power_status = alc_check_power_status,
3856#endif
c97259df 3857 .reboot_notify = alc_shutup,
1da177e4
LT
3858};
3859
c027ddcd
KY
3860/* replace the codec chip_name with the given string */
3861static int alc_codec_rename(struct hda_codec *codec, const char *name)
3862{
3863 kfree(codec->chip_name);
3864 codec->chip_name = kstrdup(name, GFP_KERNEL);
3865 if (!codec->chip_name) {
3866 alc_free(codec);
3867 return -ENOMEM;
3868 }
3869 return 0;
3870}
3871
2fa522be
TI
3872/*
3873 * Test configuration for debugging
3874 *
3875 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3876 * enum controls.
3877 */
3878#ifdef CONFIG_SND_DEBUG
3879static hda_nid_t alc880_test_dac_nids[4] = {
3880 0x02, 0x03, 0x04, 0x05
3881};
3882
3883static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3884 .num_items = 7,
2fa522be
TI
3885 .items = {
3886 { "In-1", 0x0 },
3887 { "In-2", 0x1 },
3888 { "In-3", 0x2 },
3889 { "In-4", 0x3 },
3890 { "CD", 0x4 },
ae6b813a
TI
3891 { "Front", 0x5 },
3892 { "Surround", 0x6 },
2fa522be
TI
3893 },
3894};
3895
d2a6d7dc 3896static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3897 { 2, NULL },
fd2c326d 3898 { 4, NULL },
2fa522be 3899 { 6, NULL },
fd2c326d 3900 { 8, NULL },
2fa522be
TI
3901};
3902
9c7f852e
TI
3903static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3904 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3905{
3906 static char *texts[] = {
3907 "N/A", "Line Out", "HP Out",
3908 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3909 };
3910 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3911 uinfo->count = 1;
3912 uinfo->value.enumerated.items = 8;
3913 if (uinfo->value.enumerated.item >= 8)
3914 uinfo->value.enumerated.item = 7;
3915 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3916 return 0;
3917}
3918
9c7f852e
TI
3919static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3920 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3921{
3922 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3923 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3924 unsigned int pin_ctl, item = 0;
3925
3926 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3927 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3928 if (pin_ctl & AC_PINCTL_OUT_EN) {
3929 if (pin_ctl & AC_PINCTL_HP_EN)
3930 item = 2;
3931 else
3932 item = 1;
3933 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3934 switch (pin_ctl & AC_PINCTL_VREFEN) {
3935 case AC_PINCTL_VREF_HIZ: item = 3; break;
3936 case AC_PINCTL_VREF_50: item = 4; break;
3937 case AC_PINCTL_VREF_GRD: item = 5; break;
3938 case AC_PINCTL_VREF_80: item = 6; break;
3939 case AC_PINCTL_VREF_100: item = 7; break;
3940 }
3941 }
3942 ucontrol->value.enumerated.item[0] = item;
3943 return 0;
3944}
3945
9c7f852e
TI
3946static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3947 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3948{
3949 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3950 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3951 static unsigned int ctls[] = {
3952 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3953 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3954 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3955 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3956 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3957 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3958 };
3959 unsigned int old_ctl, new_ctl;
3960
3961 old_ctl = snd_hda_codec_read(codec, nid, 0,
3962 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3963 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3964 if (old_ctl != new_ctl) {
82beb8fd
TI
3965 int val;
3966 snd_hda_codec_write_cache(codec, nid, 0,
3967 AC_VERB_SET_PIN_WIDGET_CONTROL,
3968 new_ctl);
47fd830a
TI
3969 val = ucontrol->value.enumerated.item[0] >= 3 ?
3970 HDA_AMP_MUTE : 0;
3971 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3972 HDA_AMP_MUTE, val);
2fa522be
TI
3973 return 1;
3974 }
3975 return 0;
3976}
3977
9c7f852e
TI
3978static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3979 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3980{
3981 static char *texts[] = {
3982 "Front", "Surround", "CLFE", "Side"
3983 };
3984 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3985 uinfo->count = 1;
3986 uinfo->value.enumerated.items = 4;
3987 if (uinfo->value.enumerated.item >= 4)
3988 uinfo->value.enumerated.item = 3;
3989 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3990 return 0;
3991}
3992
9c7f852e
TI
3993static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3994 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3995{
3996 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3997 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3998 unsigned int sel;
3999
4000 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4001 ucontrol->value.enumerated.item[0] = sel & 3;
4002 return 0;
4003}
4004
9c7f852e
TI
4005static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4006 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4007{
4008 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4009 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4010 unsigned int sel;
4011
4012 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4013 if (ucontrol->value.enumerated.item[0] != sel) {
4014 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4015 snd_hda_codec_write_cache(codec, nid, 0,
4016 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4017 return 1;
4018 }
4019 return 0;
4020}
4021
4022#define PIN_CTL_TEST(xname,nid) { \
4023 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4024 .name = xname, \
5b0cb1d8 4025 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4026 .info = alc_test_pin_ctl_info, \
4027 .get = alc_test_pin_ctl_get, \
4028 .put = alc_test_pin_ctl_put, \
4029 .private_value = nid \
4030 }
4031
4032#define PIN_SRC_TEST(xname,nid) { \
4033 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4034 .name = xname, \
5b0cb1d8 4035 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4036 .info = alc_test_pin_src_info, \
4037 .get = alc_test_pin_src_get, \
4038 .put = alc_test_pin_src_put, \
4039 .private_value = nid \
4040 }
4041
c8b6bf9b 4042static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4044 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4045 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4046 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4047 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4048 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4049 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4050 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4051 PIN_CTL_TEST("Front Pin Mode", 0x14),
4052 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4053 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4054 PIN_CTL_TEST("Side Pin Mode", 0x17),
4055 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4056 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4057 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4058 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4059 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4060 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4061 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4062 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4063 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4064 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4065 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4066 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4067 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4068 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4069 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4070 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4071 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4072 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4073 {
4074 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4075 .name = "Channel Mode",
df694daa
KY
4076 .info = alc_ch_mode_info,
4077 .get = alc_ch_mode_get,
4078 .put = alc_ch_mode_put,
2fa522be
TI
4079 },
4080 { } /* end */
4081};
4082
4083static struct hda_verb alc880_test_init_verbs[] = {
4084 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4085 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4087 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4088 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4089 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4090 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4093 /* Vol output for 0x0c-0x0f */
05acb863
TI
4094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4095 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4096 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4097 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4098 /* Set output pins 0x14-0x17 */
05acb863
TI
4099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4102 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4103 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4105 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4106 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4107 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4108 /* Set input pins 0x18-0x1c */
16ded525
TI
4109 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4110 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4111 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4112 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4113 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4114 /* Mute input pins 0x18-0x1b */
05acb863
TI
4115 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4116 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4117 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4118 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4119 /* ADC set up */
05acb863 4120 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4121 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4123 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4124 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4125 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4126 /* Analog input/passthru */
4127 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4128 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4129 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4130 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4132 { }
4133};
4134#endif
4135
1da177e4
LT
4136/*
4137 */
4138
f5fcc13c
TI
4139static const char *alc880_models[ALC880_MODEL_LAST] = {
4140 [ALC880_3ST] = "3stack",
4141 [ALC880_TCL_S700] = "tcl",
4142 [ALC880_3ST_DIG] = "3stack-digout",
4143 [ALC880_CLEVO] = "clevo",
4144 [ALC880_5ST] = "5stack",
4145 [ALC880_5ST_DIG] = "5stack-digout",
4146 [ALC880_W810] = "w810",
4147 [ALC880_Z71V] = "z71v",
4148 [ALC880_6ST] = "6stack",
4149 [ALC880_6ST_DIG] = "6stack-digout",
4150 [ALC880_ASUS] = "asus",
4151 [ALC880_ASUS_W1V] = "asus-w1v",
4152 [ALC880_ASUS_DIG] = "asus-dig",
4153 [ALC880_ASUS_DIG2] = "asus-dig2",
4154 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4155 [ALC880_UNIWILL_P53] = "uniwill-p53",
4156 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4157 [ALC880_F1734] = "F1734",
4158 [ALC880_LG] = "lg",
4159 [ALC880_LG_LW] = "lg-lw",
df99cd33 4160 [ALC880_MEDION_RIM] = "medion",
2fa522be 4161#ifdef CONFIG_SND_DEBUG
f5fcc13c 4162 [ALC880_TEST] = "test",
2fa522be 4163#endif
f5fcc13c
TI
4164 [ALC880_AUTO] = "auto",
4165};
4166
4167static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4168 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4169 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4170 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4171 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4172 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4173 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4174 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4175 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4176 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4177 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4178 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4179 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4180 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4181 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4182 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4183 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4184 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4185 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4186 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4187 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4188 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4189 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4190 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4191 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4192 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4193 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4194 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4195 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4196 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4197 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4198 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4199 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4200 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4201 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4202 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4203 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4204 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4205 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4206 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4207 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4208 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4209 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4210 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4211 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4212 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4213 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4214 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4215 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4216 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 4217 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 4218 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4219 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4220 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4221 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4222 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4223 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4224 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4225 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4226 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4227 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4228 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4229 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4230 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4231 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4232 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4233 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4234 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4235 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4236 /* default Intel */
4237 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4238 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4239 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4240 {}
4241};
4242
16ded525 4243/*
df694daa 4244 * ALC880 codec presets
16ded525 4245 */
16ded525
TI
4246static struct alc_config_preset alc880_presets[] = {
4247 [ALC880_3ST] = {
e9edcee0 4248 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4249 .init_verbs = { alc880_volume_init_verbs,
4250 alc880_pin_3stack_init_verbs },
16ded525 4251 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4252 .dac_nids = alc880_dac_nids,
16ded525
TI
4253 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4254 .channel_mode = alc880_threestack_modes,
4e195a7b 4255 .need_dac_fix = 1,
16ded525
TI
4256 .input_mux = &alc880_capture_source,
4257 },
4258 [ALC880_3ST_DIG] = {
e9edcee0 4259 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4260 .init_verbs = { alc880_volume_init_verbs,
4261 alc880_pin_3stack_init_verbs },
16ded525 4262 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4263 .dac_nids = alc880_dac_nids,
4264 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4265 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4266 .channel_mode = alc880_threestack_modes,
4e195a7b 4267 .need_dac_fix = 1,
16ded525
TI
4268 .input_mux = &alc880_capture_source,
4269 },
df694daa
KY
4270 [ALC880_TCL_S700] = {
4271 .mixers = { alc880_tcl_s700_mixer },
4272 .init_verbs = { alc880_volume_init_verbs,
4273 alc880_pin_tcl_S700_init_verbs,
4274 alc880_gpio2_init_verbs },
4275 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4276 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4277 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4278 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4279 .hp_nid = 0x03,
4280 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4281 .channel_mode = alc880_2_jack_modes,
4282 .input_mux = &alc880_capture_source,
4283 },
16ded525 4284 [ALC880_5ST] = {
f12ab1e0
TI
4285 .mixers = { alc880_three_stack_mixer,
4286 alc880_five_stack_mixer},
4287 .init_verbs = { alc880_volume_init_verbs,
4288 alc880_pin_5stack_init_verbs },
16ded525
TI
4289 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4290 .dac_nids = alc880_dac_nids,
16ded525
TI
4291 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4292 .channel_mode = alc880_fivestack_modes,
4293 .input_mux = &alc880_capture_source,
4294 },
4295 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4296 .mixers = { alc880_three_stack_mixer,
4297 alc880_five_stack_mixer },
4298 .init_verbs = { alc880_volume_init_verbs,
4299 alc880_pin_5stack_init_verbs },
16ded525
TI
4300 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4301 .dac_nids = alc880_dac_nids,
4302 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4303 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4304 .channel_mode = alc880_fivestack_modes,
4305 .input_mux = &alc880_capture_source,
4306 },
b6482d48
TI
4307 [ALC880_6ST] = {
4308 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4309 .init_verbs = { alc880_volume_init_verbs,
4310 alc880_pin_6stack_init_verbs },
b6482d48
TI
4311 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4312 .dac_nids = alc880_6st_dac_nids,
4313 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4314 .channel_mode = alc880_sixstack_modes,
4315 .input_mux = &alc880_6stack_capture_source,
4316 },
16ded525 4317 [ALC880_6ST_DIG] = {
e9edcee0 4318 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4319 .init_verbs = { alc880_volume_init_verbs,
4320 alc880_pin_6stack_init_verbs },
16ded525
TI
4321 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4322 .dac_nids = alc880_6st_dac_nids,
4323 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4324 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4325 .channel_mode = alc880_sixstack_modes,
4326 .input_mux = &alc880_6stack_capture_source,
4327 },
4328 [ALC880_W810] = {
e9edcee0 4329 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4330 .init_verbs = { alc880_volume_init_verbs,
4331 alc880_pin_w810_init_verbs,
b0af0de5 4332 alc880_gpio2_init_verbs },
16ded525
TI
4333 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4334 .dac_nids = alc880_w810_dac_nids,
4335 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4336 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4337 .channel_mode = alc880_w810_modes,
4338 .input_mux = &alc880_capture_source,
4339 },
4340 [ALC880_Z71V] = {
e9edcee0 4341 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4342 .init_verbs = { alc880_volume_init_verbs,
4343 alc880_pin_z71v_init_verbs },
16ded525
TI
4344 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4345 .dac_nids = alc880_z71v_dac_nids,
4346 .dig_out_nid = ALC880_DIGOUT_NID,
4347 .hp_nid = 0x03,
e9edcee0
TI
4348 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4349 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4350 .input_mux = &alc880_capture_source,
4351 },
4352 [ALC880_F1734] = {
e9edcee0 4353 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4354 .init_verbs = { alc880_volume_init_verbs,
4355 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4356 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4357 .dac_nids = alc880_f1734_dac_nids,
4358 .hp_nid = 0x02,
4359 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4360 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4361 .input_mux = &alc880_f1734_capture_source,
4362 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4363 .setup = alc880_uniwill_p53_setup,
4364 .init_hook = alc_automute_amp,
16ded525
TI
4365 },
4366 [ALC880_ASUS] = {
e9edcee0 4367 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4368 .init_verbs = { alc880_volume_init_verbs,
4369 alc880_pin_asus_init_verbs,
e9edcee0
TI
4370 alc880_gpio1_init_verbs },
4371 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4372 .dac_nids = alc880_asus_dac_nids,
4373 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4374 .channel_mode = alc880_asus_modes,
4e195a7b 4375 .need_dac_fix = 1,
16ded525
TI
4376 .input_mux = &alc880_capture_source,
4377 },
4378 [ALC880_ASUS_DIG] = {
e9edcee0 4379 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4380 .init_verbs = { alc880_volume_init_verbs,
4381 alc880_pin_asus_init_verbs,
e9edcee0
TI
4382 alc880_gpio1_init_verbs },
4383 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4384 .dac_nids = alc880_asus_dac_nids,
16ded525 4385 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4386 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4387 .channel_mode = alc880_asus_modes,
4e195a7b 4388 .need_dac_fix = 1,
16ded525
TI
4389 .input_mux = &alc880_capture_source,
4390 },
df694daa
KY
4391 [ALC880_ASUS_DIG2] = {
4392 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4393 .init_verbs = { alc880_volume_init_verbs,
4394 alc880_pin_asus_init_verbs,
df694daa
KY
4395 alc880_gpio2_init_verbs }, /* use GPIO2 */
4396 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4397 .dac_nids = alc880_asus_dac_nids,
4398 .dig_out_nid = ALC880_DIGOUT_NID,
4399 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4400 .channel_mode = alc880_asus_modes,
4e195a7b 4401 .need_dac_fix = 1,
df694daa
KY
4402 .input_mux = &alc880_capture_source,
4403 },
16ded525 4404 [ALC880_ASUS_W1V] = {
e9edcee0 4405 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4406 .init_verbs = { alc880_volume_init_verbs,
4407 alc880_pin_asus_init_verbs,
e9edcee0
TI
4408 alc880_gpio1_init_verbs },
4409 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4410 .dac_nids = alc880_asus_dac_nids,
16ded525 4411 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4412 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4413 .channel_mode = alc880_asus_modes,
4e195a7b 4414 .need_dac_fix = 1,
16ded525
TI
4415 .input_mux = &alc880_capture_source,
4416 },
4417 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4418 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4419 .init_verbs = { alc880_volume_init_verbs,
4420 alc880_pin_asus_init_verbs },
e9edcee0
TI
4421 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4422 .dac_nids = alc880_asus_dac_nids,
16ded525 4423 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4424 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4425 .channel_mode = alc880_asus_modes,
4e195a7b 4426 .need_dac_fix = 1,
16ded525
TI
4427 .input_mux = &alc880_capture_source,
4428 },
ccc656ce
KY
4429 [ALC880_UNIWILL] = {
4430 .mixers = { alc880_uniwill_mixer },
4431 .init_verbs = { alc880_volume_init_verbs,
4432 alc880_uniwill_init_verbs },
4433 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4434 .dac_nids = alc880_asus_dac_nids,
4435 .dig_out_nid = ALC880_DIGOUT_NID,
4436 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4437 .channel_mode = alc880_threestack_modes,
4438 .need_dac_fix = 1,
4439 .input_mux = &alc880_capture_source,
4440 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4441 .setup = alc880_uniwill_setup,
a9fd4f3f 4442 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4443 },
4444 [ALC880_UNIWILL_P53] = {
4445 .mixers = { alc880_uniwill_p53_mixer },
4446 .init_verbs = { alc880_volume_init_verbs,
4447 alc880_uniwill_p53_init_verbs },
4448 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4449 .dac_nids = alc880_asus_dac_nids,
4450 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4451 .channel_mode = alc880_threestack_modes,
4452 .input_mux = &alc880_capture_source,
4453 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4454 .setup = alc880_uniwill_p53_setup,
4455 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4456 },
4457 [ALC880_FUJITSU] = {
45bdd1c1 4458 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4459 .init_verbs = { alc880_volume_init_verbs,
4460 alc880_uniwill_p53_init_verbs,
4461 alc880_beep_init_verbs },
4462 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4463 .dac_nids = alc880_dac_nids,
d53d7d9e 4464 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4465 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4466 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4467 .input_mux = &alc880_capture_source,
4468 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4469 .setup = alc880_uniwill_p53_setup,
4470 .init_hook = alc_automute_amp,
ccc656ce 4471 },
df694daa
KY
4472 [ALC880_CLEVO] = {
4473 .mixers = { alc880_three_stack_mixer },
4474 .init_verbs = { alc880_volume_init_verbs,
4475 alc880_pin_clevo_init_verbs },
4476 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4477 .dac_nids = alc880_dac_nids,
4478 .hp_nid = 0x03,
4479 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4480 .channel_mode = alc880_threestack_modes,
4e195a7b 4481 .need_dac_fix = 1,
df694daa
KY
4482 .input_mux = &alc880_capture_source,
4483 },
ae6b813a
TI
4484 [ALC880_LG] = {
4485 .mixers = { alc880_lg_mixer },
4486 .init_verbs = { alc880_volume_init_verbs,
4487 alc880_lg_init_verbs },
4488 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4489 .dac_nids = alc880_lg_dac_nids,
4490 .dig_out_nid = ALC880_DIGOUT_NID,
4491 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4492 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4493 .need_dac_fix = 1,
ae6b813a 4494 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4495 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4496 .setup = alc880_lg_setup,
4497 .init_hook = alc_automute_amp,
cb53c626
TI
4498#ifdef CONFIG_SND_HDA_POWER_SAVE
4499 .loopbacks = alc880_lg_loopbacks,
4500#endif
ae6b813a 4501 },
d681518a
TI
4502 [ALC880_LG_LW] = {
4503 .mixers = { alc880_lg_lw_mixer },
4504 .init_verbs = { alc880_volume_init_verbs,
4505 alc880_lg_lw_init_verbs },
0a8c5da3 4506 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4507 .dac_nids = alc880_dac_nids,
4508 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4509 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4510 .channel_mode = alc880_lg_lw_modes,
d681518a 4511 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4512 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4513 .setup = alc880_lg_lw_setup,
4514 .init_hook = alc_automute_amp,
d681518a 4515 },
df99cd33
TI
4516 [ALC880_MEDION_RIM] = {
4517 .mixers = { alc880_medion_rim_mixer },
4518 .init_verbs = { alc880_volume_init_verbs,
4519 alc880_medion_rim_init_verbs,
4520 alc_gpio2_init_verbs },
4521 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4522 .dac_nids = alc880_dac_nids,
4523 .dig_out_nid = ALC880_DIGOUT_NID,
4524 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4525 .channel_mode = alc880_2_jack_modes,
4526 .input_mux = &alc880_medion_rim_capture_source,
4527 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4528 .setup = alc880_medion_rim_setup,
4529 .init_hook = alc880_medion_rim_automute,
df99cd33 4530 },
16ded525
TI
4531#ifdef CONFIG_SND_DEBUG
4532 [ALC880_TEST] = {
e9edcee0
TI
4533 .mixers = { alc880_test_mixer },
4534 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4535 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4536 .dac_nids = alc880_test_dac_nids,
4537 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4538 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4539 .channel_mode = alc880_test_modes,
4540 .input_mux = &alc880_test_capture_source,
4541 },
4542#endif
4543};
4544
e9edcee0
TI
4545/*
4546 * Automatic parse of I/O pins from the BIOS configuration
4547 */
4548
e9edcee0
TI
4549enum {
4550 ALC_CTL_WIDGET_VOL,
4551 ALC_CTL_WIDGET_MUTE,
4552 ALC_CTL_BIND_MUTE,
4553};
c8b6bf9b 4554static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4555 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4556 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4557 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4558};
4559
4560/* add dynamic controls */
f12ab1e0
TI
4561static int add_control(struct alc_spec *spec, int type, const char *name,
4562 unsigned long val)
e9edcee0 4563{
c8b6bf9b 4564 struct snd_kcontrol_new *knew;
e9edcee0 4565
603c4019
TI
4566 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4567 knew = snd_array_new(&spec->kctls);
4568 if (!knew)
4569 return -ENOMEM;
e9edcee0 4570 *knew = alc880_control_templates[type];
543537bd 4571 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4572 if (!knew->name)
e9edcee0 4573 return -ENOMEM;
4d02d1b6 4574 if (get_amp_nid_(val))
5e26dfd0 4575 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4576 knew->private_value = val;
e9edcee0
TI
4577 return 0;
4578}
4579
0afe5f89
TI
4580static int add_control_with_pfx(struct alc_spec *spec, int type,
4581 const char *pfx, const char *dir,
4582 const char *sfx, unsigned long val)
4583{
4584 char name[32];
4585 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4586 return add_control(spec, type, name, val);
4587}
4588
4589#define add_pb_vol_ctrl(spec, type, pfx, val) \
4590 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4591#define add_pb_sw_ctrl(spec, type, pfx, val) \
4592 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4593
e9edcee0
TI
4594#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4595#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4596#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4597#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4598#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4599#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4600#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4601#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4602#define ALC880_PIN_CD_NID 0x1c
4603
4604/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4605static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4606 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4607{
4608 hda_nid_t nid;
4609 int assigned[4];
4610 int i, j;
4611
4612 memset(assigned, 0, sizeof(assigned));
b0af0de5 4613 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4614
4615 /* check the pins hardwired to audio widget */
4616 for (i = 0; i < cfg->line_outs; i++) {
4617 nid = cfg->line_out_pins[i];
4618 if (alc880_is_fixed_pin(nid)) {
4619 int idx = alc880_fixed_pin_idx(nid);
5014f193 4620 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4621 assigned[idx] = 1;
4622 }
4623 }
4624 /* left pins can be connect to any audio widget */
4625 for (i = 0; i < cfg->line_outs; i++) {
4626 nid = cfg->line_out_pins[i];
4627 if (alc880_is_fixed_pin(nid))
4628 continue;
4629 /* search for an empty channel */
4630 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4631 if (!assigned[j]) {
4632 spec->multiout.dac_nids[i] =
4633 alc880_idx_to_dac(j);
e9edcee0
TI
4634 assigned[j] = 1;
4635 break;
4636 }
4637 }
4638 }
4639 spec->multiout.num_dacs = cfg->line_outs;
4640 return 0;
4641}
4642
4643/* add playback controls from the parsed DAC table */
df694daa
KY
4644static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4645 const struct auto_pin_cfg *cfg)
e9edcee0 4646{
f12ab1e0
TI
4647 static const char *chname[4] = {
4648 "Front", "Surround", NULL /*CLFE*/, "Side"
4649 };
e9edcee0
TI
4650 hda_nid_t nid;
4651 int i, err;
4652
4653 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4654 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4655 continue;
4656 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4657 if (i == 2) {
4658 /* Center/LFE */
0afe5f89
TI
4659 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4660 "Center",
f12ab1e0
TI
4661 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4662 HDA_OUTPUT));
4663 if (err < 0)
e9edcee0 4664 return err;
0afe5f89
TI
4665 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4666 "LFE",
f12ab1e0
TI
4667 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4668 HDA_OUTPUT));
4669 if (err < 0)
e9edcee0 4670 return err;
0afe5f89
TI
4671 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4672 "Center",
f12ab1e0
TI
4673 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4674 HDA_INPUT));
4675 if (err < 0)
e9edcee0 4676 return err;
0afe5f89
TI
4677 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4678 "LFE",
f12ab1e0
TI
4679 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4680 HDA_INPUT));
4681 if (err < 0)
e9edcee0
TI
4682 return err;
4683 } else {
cb162b6b
TI
4684 const char *pfx;
4685 if (cfg->line_outs == 1 &&
4686 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4687 pfx = "Speaker";
4688 else
4689 pfx = chname[i];
0afe5f89 4690 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4691 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4692 HDA_OUTPUT));
4693 if (err < 0)
e9edcee0 4694 return err;
0afe5f89 4695 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4696 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4697 HDA_INPUT));
4698 if (err < 0)
e9edcee0
TI
4699 return err;
4700 }
4701 }
e9edcee0
TI
4702 return 0;
4703}
4704
8d88bc3d
TI
4705/* add playback controls for speaker and HP outputs */
4706static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4707 const char *pfx)
e9edcee0
TI
4708{
4709 hda_nid_t nid;
4710 int err;
4711
f12ab1e0 4712 if (!pin)
e9edcee0
TI
4713 return 0;
4714
4715 if (alc880_is_fixed_pin(pin)) {
4716 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4717 /* specify the DAC as the extra output */
f12ab1e0 4718 if (!spec->multiout.hp_nid)
e9edcee0 4719 spec->multiout.hp_nid = nid;
82bc955f
TI
4720 else
4721 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4722 /* control HP volume/switch on the output mixer amp */
4723 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4724 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4725 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4726 if (err < 0)
e9edcee0 4727 return err;
0afe5f89 4728 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4729 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4730 if (err < 0)
e9edcee0
TI
4731 return err;
4732 } else if (alc880_is_multi_pin(pin)) {
4733 /* set manual connection */
e9edcee0 4734 /* we have only a switch on HP-out PIN */
0afe5f89 4735 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4736 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4737 if (err < 0)
e9edcee0
TI
4738 return err;
4739 }
4740 return 0;
4741}
4742
4743/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4744static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4745 const char *ctlname,
df694daa 4746 int idx, hda_nid_t mix_nid)
e9edcee0 4747{
df694daa 4748 int err;
e9edcee0 4749
0afe5f89 4750 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4751 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4752 if (err < 0)
e9edcee0 4753 return err;
0afe5f89 4754 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4755 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4756 if (err < 0)
e9edcee0
TI
4757 return err;
4758 return 0;
4759}
4760
05f5f477
TI
4761static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4762{
4763 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4764 return (pincap & AC_PINCAP_IN) != 0;
4765}
4766
e9edcee0 4767/* create playback/capture controls for input pins */
05f5f477
TI
4768static int alc_auto_create_input_ctls(struct hda_codec *codec,
4769 const struct auto_pin_cfg *cfg,
4770 hda_nid_t mixer,
4771 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4772{
05f5f477 4773 struct alc_spec *spec = codec->spec;
61b9b9b1 4774 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4775 int i, err, idx;
e9edcee0
TI
4776
4777 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4778 hda_nid_t pin;
4779
4780 pin = cfg->input_pins[i];
4781 if (!alc_is_input_pin(codec, pin))
4782 continue;
4783
4784 if (mixer) {
4785 idx = get_connection_index(codec, mixer, pin);
4786 if (idx >= 0) {
4787 err = new_analog_input(spec, pin,
4788 auto_pin_cfg_labels[i],
4789 idx, mixer);
4790 if (err < 0)
4791 return err;
4792 }
4793 }
4794
4795 if (!cap1)
4796 continue;
4797 idx = get_connection_index(codec, cap1, pin);
4798 if (idx < 0 && cap2)
4799 idx = get_connection_index(codec, cap2, pin);
4800 if (idx >= 0) {
f12ab1e0
TI
4801 imux->items[imux->num_items].label =
4802 auto_pin_cfg_labels[i];
05f5f477 4803 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4804 imux->num_items++;
4805 }
4806 }
4807 return 0;
4808}
4809
05f5f477
TI
4810static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4811 const struct auto_pin_cfg *cfg)
4812{
4813 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4814}
4815
f6c7e546
TI
4816static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4817 unsigned int pin_type)
4818{
4819 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4820 pin_type);
4821 /* unmute pin */
d260cdf6
TI
4822 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4823 AMP_OUT_UNMUTE);
f6c7e546
TI
4824}
4825
df694daa
KY
4826static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4827 hda_nid_t nid, int pin_type,
e9edcee0
TI
4828 int dac_idx)
4829{
f6c7e546 4830 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4831 /* need the manual connection? */
4832 if (alc880_is_multi_pin(nid)) {
4833 struct alc_spec *spec = codec->spec;
4834 int idx = alc880_multi_pin_idx(nid);
4835 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4836 AC_VERB_SET_CONNECT_SEL,
4837 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4838 }
4839}
4840
baba8ee9
TI
4841static int get_pin_type(int line_out_type)
4842{
4843 if (line_out_type == AUTO_PIN_HP_OUT)
4844 return PIN_HP;
4845 else
4846 return PIN_OUT;
4847}
4848
e9edcee0
TI
4849static void alc880_auto_init_multi_out(struct hda_codec *codec)
4850{
4851 struct alc_spec *spec = codec->spec;
4852 int i;
ea1fb29a 4853
e9edcee0
TI
4854 for (i = 0; i < spec->autocfg.line_outs; i++) {
4855 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4856 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4857 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4858 }
4859}
4860
8d88bc3d 4861static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4862{
4863 struct alc_spec *spec = codec->spec;
4864 hda_nid_t pin;
4865
82bc955f 4866 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4867 if (pin) /* connect to front */
4868 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4869 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4870 if (pin) /* connect to front */
4871 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4872}
4873
4874static void alc880_auto_init_analog_input(struct hda_codec *codec)
4875{
4876 struct alc_spec *spec = codec->spec;
4877 int i;
4878
4879 for (i = 0; i < AUTO_PIN_LAST; i++) {
4880 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 4881 if (alc_is_input_pin(codec, nid)) {
23f0c048 4882 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4883 if (nid != ALC880_PIN_CD_NID &&
4884 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4885 snd_hda_codec_write(codec, nid, 0,
4886 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4887 AMP_OUT_MUTE);
4888 }
4889 }
4890}
4891
4892/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4893/* return 1 if successful, 0 if the proper config is not found,
4894 * or a negative error code
4895 */
e9edcee0
TI
4896static int alc880_parse_auto_config(struct hda_codec *codec)
4897{
4898 struct alc_spec *spec = codec->spec;
6a05ac4a 4899 int i, err;
df694daa 4900 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4901
f12ab1e0
TI
4902 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4903 alc880_ignore);
4904 if (err < 0)
e9edcee0 4905 return err;
f12ab1e0 4906 if (!spec->autocfg.line_outs)
e9edcee0 4907 return 0; /* can't find valid BIOS pin config */
df694daa 4908
f12ab1e0
TI
4909 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4910 if (err < 0)
4911 return err;
4912 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4913 if (err < 0)
4914 return err;
4915 err = alc880_auto_create_extra_out(spec,
4916 spec->autocfg.speaker_pins[0],
4917 "Speaker");
4918 if (err < 0)
4919 return err;
4920 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4921 "Headphone");
4922 if (err < 0)
4923 return err;
05f5f477 4924 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 4925 if (err < 0)
e9edcee0
TI
4926 return err;
4927
4928 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4929
6a05ac4a
TI
4930 /* check multiple SPDIF-out (for recent codecs) */
4931 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4932 hda_nid_t dig_nid;
4933 err = snd_hda_get_connections(codec,
4934 spec->autocfg.dig_out_pins[i],
4935 &dig_nid, 1);
4936 if (err < 0)
4937 continue;
4938 if (!i)
4939 spec->multiout.dig_out_nid = dig_nid;
4940 else {
4941 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 4942 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
6a05ac4a 4943 break;
71121d9f 4944 spec->slave_dig_outs[i - 1] = dig_nid;
6a05ac4a
TI
4945 }
4946 }
e9edcee0
TI
4947 if (spec->autocfg.dig_in_pin)
4948 spec->dig_in_nid = ALC880_DIGIN_NID;
4949
603c4019 4950 if (spec->kctls.list)
d88897ea 4951 add_mixer(spec, spec->kctls.list);
e9edcee0 4952
d88897ea 4953 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4954
a1e8d2da 4955 spec->num_mux_defs = 1;
61b9b9b1 4956 spec->input_mux = &spec->private_imux[0];
e9edcee0 4957
6227cdce 4958 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 4959
e9edcee0
TI
4960 return 1;
4961}
4962
ae6b813a
TI
4963/* additional initialization for auto-configuration model */
4964static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4965{
f6c7e546 4966 struct alc_spec *spec = codec->spec;
e9edcee0 4967 alc880_auto_init_multi_out(codec);
8d88bc3d 4968 alc880_auto_init_extra_out(codec);
e9edcee0 4969 alc880_auto_init_analog_input(codec);
f6c7e546 4970 if (spec->unsol_event)
7fb0d78f 4971 alc_inithook(codec);
e9edcee0
TI
4972}
4973
b59bdf3b
TI
4974/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4975 * one of two digital mic pins, e.g. on ALC272
4976 */
4977static void fixup_automic_adc(struct hda_codec *codec)
4978{
4979 struct alc_spec *spec = codec->spec;
4980 int i;
4981
4982 for (i = 0; i < spec->num_adc_nids; i++) {
4983 hda_nid_t cap = spec->capsrc_nids ?
4984 spec->capsrc_nids[i] : spec->adc_nids[i];
4985 int iidx, eidx;
4986
4987 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4988 if (iidx < 0)
4989 continue;
4990 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4991 if (eidx < 0)
4992 continue;
4993 spec->int_mic.mux_idx = iidx;
4994 spec->ext_mic.mux_idx = eidx;
4995 if (spec->capsrc_nids)
4996 spec->capsrc_nids += i;
4997 spec->adc_nids += i;
4998 spec->num_adc_nids = 1;
4999 return;
5000 }
5001 snd_printd(KERN_INFO "hda_codec: %s: "
5002 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5003 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5004 spec->auto_mic = 0; /* disable auto-mic to be sure */
5005}
5006
eaa9b3a7
TI
5007/* choose the ADC/MUX containing the input pin and initialize the setup */
5008static void fixup_single_adc(struct hda_codec *codec)
5009{
5010 struct alc_spec *spec = codec->spec;
d2db09b8 5011 hda_nid_t pin = 0;
eaa9b3a7
TI
5012 int i;
5013
5014 /* search for the input pin; there must be only one */
5015 for (i = 0; i < AUTO_PIN_LAST; i++) {
5016 if (spec->autocfg.input_pins[i]) {
5017 pin = spec->autocfg.input_pins[i];
5018 break;
5019 }
5020 }
5021 if (!pin)
5022 return;
5023
5024 /* set the default connection to that pin */
5025 for (i = 0; i < spec->num_adc_nids; i++) {
5026 hda_nid_t cap = spec->capsrc_nids ?
5027 spec->capsrc_nids[i] : spec->adc_nids[i];
5028 int idx;
5029
5030 idx = get_connection_index(codec, cap, pin);
5031 if (idx < 0)
5032 continue;
5033 /* use only this ADC */
5034 if (spec->capsrc_nids)
5035 spec->capsrc_nids += i;
5036 spec->adc_nids += i;
5037 spec->num_adc_nids = 1;
5038 /* select or unmute this route */
5039 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5040 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5041 HDA_AMP_MUTE, 0);
5042 } else {
5043 snd_hda_codec_write_cache(codec, cap, 0,
5044 AC_VERB_SET_CONNECT_SEL, idx);
5045 }
5046 return;
5047 }
5048}
5049
b59bdf3b 5050static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5051{
b59bdf3b 5052 struct alc_spec *spec = codec->spec;
a23b688f
TI
5053 static struct snd_kcontrol_new *caps[2][3] = {
5054 { alc_capture_mixer_nosrc1,
5055 alc_capture_mixer_nosrc2,
5056 alc_capture_mixer_nosrc3 },
5057 { alc_capture_mixer1,
5058 alc_capture_mixer2,
5059 alc_capture_mixer3 },
f9e336f6 5060 };
a23b688f 5061 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7
TI
5062 int mux = 0;
5063 if (spec->auto_mic)
b59bdf3b 5064 fixup_automic_adc(codec);
eaa9b3a7
TI
5065 else if (spec->input_mux) {
5066 if (spec->input_mux->num_items > 1)
5067 mux = 1;
5068 else if (spec->input_mux->num_items == 1)
5069 fixup_single_adc(codec);
5070 }
a23b688f
TI
5071 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
5072 }
f9e336f6
TI
5073}
5074
6694635d
TI
5075/* fill adc_nids (and capsrc_nids) containing all active input pins */
5076static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5077 int num_nids)
5078{
5079 struct alc_spec *spec = codec->spec;
5080 int n;
5081 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5082
5083 for (n = 0; n < num_nids; n++) {
5084 hda_nid_t adc, cap;
5085 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5086 int nconns, i, j;
5087
5088 adc = nids[n];
5089 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5090 continue;
5091 cap = adc;
5092 nconns = snd_hda_get_connections(codec, cap, conn,
5093 ARRAY_SIZE(conn));
5094 if (nconns == 1) {
5095 cap = conn[0];
5096 nconns = snd_hda_get_connections(codec, cap, conn,
5097 ARRAY_SIZE(conn));
5098 }
5099 if (nconns <= 0)
5100 continue;
5101 if (!fallback_adc) {
5102 fallback_adc = adc;
5103 fallback_cap = cap;
5104 }
5105 for (i = 0; i < AUTO_PIN_LAST; i++) {
5106 hda_nid_t nid = spec->autocfg.input_pins[i];
5107 if (!nid)
5108 continue;
5109 for (j = 0; j < nconns; j++) {
5110 if (conn[j] == nid)
5111 break;
5112 }
5113 if (j >= nconns)
5114 break;
5115 }
5116 if (i >= AUTO_PIN_LAST) {
5117 int num_adcs = spec->num_adc_nids;
5118 spec->private_adc_nids[num_adcs] = adc;
5119 spec->private_capsrc_nids[num_adcs] = cap;
5120 spec->num_adc_nids++;
5121 spec->adc_nids = spec->private_adc_nids;
5122 if (adc != cap)
5123 spec->capsrc_nids = spec->private_capsrc_nids;
5124 }
5125 }
5126 if (!spec->num_adc_nids) {
5127 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5128 " using fallback 0x%x\n",
5129 codec->chip_name, fallback_adc);
6694635d
TI
5130 spec->private_adc_nids[0] = fallback_adc;
5131 spec->adc_nids = spec->private_adc_nids;
5132 if (fallback_adc != fallback_cap) {
5133 spec->private_capsrc_nids[0] = fallback_cap;
5134 spec->capsrc_nids = spec->private_adc_nids;
5135 }
5136 }
5137}
5138
67d634c0 5139#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5140#define set_beep_amp(spec, nid, idx, dir) \
5141 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
67d634c0
TI
5142#else
5143#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5144#endif
45bdd1c1
TI
5145
5146/*
5147 * OK, here we have finally the patch for ALC880
5148 */
5149
1da177e4
LT
5150static int patch_alc880(struct hda_codec *codec)
5151{
5152 struct alc_spec *spec;
5153 int board_config;
df694daa 5154 int err;
1da177e4 5155
e560d8d8 5156 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5157 if (spec == NULL)
5158 return -ENOMEM;
5159
5160 codec->spec = spec;
5161
f5fcc13c
TI
5162 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5163 alc880_models,
5164 alc880_cfg_tbl);
5165 if (board_config < 0) {
9a11f1aa
TI
5166 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5167 codec->chip_name);
e9edcee0 5168 board_config = ALC880_AUTO;
1da177e4 5169 }
1da177e4 5170
e9edcee0
TI
5171 if (board_config == ALC880_AUTO) {
5172 /* automatic parse from the BIOS config */
5173 err = alc880_parse_auto_config(codec);
5174 if (err < 0) {
5175 alc_free(codec);
5176 return err;
f12ab1e0 5177 } else if (!err) {
9c7f852e
TI
5178 printk(KERN_INFO
5179 "hda_codec: Cannot set up configuration "
5180 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5181 board_config = ALC880_3ST;
5182 }
1da177e4
LT
5183 }
5184
680cd536
KK
5185 err = snd_hda_attach_beep_device(codec, 0x1);
5186 if (err < 0) {
5187 alc_free(codec);
5188 return err;
5189 }
5190
df694daa 5191 if (board_config != ALC880_AUTO)
e9c364c0 5192 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5193
1da177e4
LT
5194 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5195 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5196 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5197
1da177e4
LT
5198 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5199 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5200
f12ab1e0 5201 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5202 /* check whether NID 0x07 is valid */
54d17403 5203 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5204 /* get type */
a22d543a 5205 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5206 if (wcap != AC_WID_AUD_IN) {
5207 spec->adc_nids = alc880_adc_nids_alt;
5208 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5209 } else {
5210 spec->adc_nids = alc880_adc_nids;
5211 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5212 }
5213 }
b59bdf3b 5214 set_capture_mixer(codec);
45bdd1c1 5215 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5216
2134ea4f
TI
5217 spec->vmaster_nid = 0x0c;
5218
1da177e4 5219 codec->patch_ops = alc_patch_ops;
e9edcee0 5220 if (board_config == ALC880_AUTO)
ae6b813a 5221 spec->init_hook = alc880_auto_init;
cb53c626
TI
5222#ifdef CONFIG_SND_HDA_POWER_SAVE
5223 if (!spec->loopback.amplist)
5224 spec->loopback.amplist = alc880_loopbacks;
5225#endif
1da177e4
LT
5226
5227 return 0;
5228}
5229
e9edcee0 5230
1da177e4
LT
5231/*
5232 * ALC260 support
5233 */
5234
e9edcee0
TI
5235static hda_nid_t alc260_dac_nids[1] = {
5236 /* front */
5237 0x02,
5238};
5239
5240static hda_nid_t alc260_adc_nids[1] = {
5241 /* ADC0 */
5242 0x04,
5243};
5244
df694daa 5245static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5246 /* ADC1 */
5247 0x05,
5248};
5249
d57fdac0
JW
5250/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5251 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5252 */
5253static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5254 /* ADC0, ADC1 */
5255 0x04, 0x05
5256};
5257
e9edcee0
TI
5258#define ALC260_DIGOUT_NID 0x03
5259#define ALC260_DIGIN_NID 0x06
5260
5261static struct hda_input_mux alc260_capture_source = {
5262 .num_items = 4,
5263 .items = {
5264 { "Mic", 0x0 },
5265 { "Front Mic", 0x1 },
5266 { "Line", 0x2 },
5267 { "CD", 0x4 },
5268 },
5269};
5270
17e7aec6 5271/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5272 * headphone jack and the internal CD lines since these are the only pins at
5273 * which audio can appear. For flexibility, also allow the option of
5274 * recording the mixer output on the second ADC (ADC0 doesn't have a
5275 * connection to the mixer output).
a9430dd8 5276 */
a1e8d2da
JW
5277static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5278 {
5279 .num_items = 3,
5280 .items = {
5281 { "Mic/Line", 0x0 },
5282 { "CD", 0x4 },
5283 { "Headphone", 0x2 },
5284 },
a9430dd8 5285 },
a1e8d2da
JW
5286 {
5287 .num_items = 4,
5288 .items = {
5289 { "Mic/Line", 0x0 },
5290 { "CD", 0x4 },
5291 { "Headphone", 0x2 },
5292 { "Mixer", 0x5 },
5293 },
5294 },
5295
a9430dd8
JW
5296};
5297
a1e8d2da
JW
5298/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5299 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5300 */
a1e8d2da
JW
5301static struct hda_input_mux alc260_acer_capture_sources[2] = {
5302 {
5303 .num_items = 4,
5304 .items = {
5305 { "Mic", 0x0 },
5306 { "Line", 0x2 },
5307 { "CD", 0x4 },
5308 { "Headphone", 0x5 },
5309 },
5310 },
5311 {
5312 .num_items = 5,
5313 .items = {
5314 { "Mic", 0x0 },
5315 { "Line", 0x2 },
5316 { "CD", 0x4 },
5317 { "Headphone", 0x6 },
5318 { "Mixer", 0x5 },
5319 },
0bfc90e9
JW
5320 },
5321};
cc959489
MS
5322
5323/* Maxdata Favorit 100XS */
5324static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5325 {
5326 .num_items = 2,
5327 .items = {
5328 { "Line/Mic", 0x0 },
5329 { "CD", 0x4 },
5330 },
5331 },
5332 {
5333 .num_items = 3,
5334 .items = {
5335 { "Line/Mic", 0x0 },
5336 { "CD", 0x4 },
5337 { "Mixer", 0x5 },
5338 },
5339 },
5340};
5341
1da177e4
LT
5342/*
5343 * This is just place-holder, so there's something for alc_build_pcms to look
5344 * at when it calculates the maximum number of channels. ALC260 has no mixer
5345 * element which allows changing the channel mode, so the verb list is
5346 * never used.
5347 */
d2a6d7dc 5348static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5349 { 2, NULL },
5350};
5351
df694daa
KY
5352
5353/* Mixer combinations
5354 *
5355 * basic: base_output + input + pc_beep + capture
5356 * HP: base_output + input + capture_alt
5357 * HP_3013: hp_3013 + input + capture
5358 * fujitsu: fujitsu + capture
0bfc90e9 5359 * acer: acer + capture
df694daa
KY
5360 */
5361
5362static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5363 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5364 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5366 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5367 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5368 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5369 { } /* end */
f12ab1e0 5370};
1da177e4 5371
df694daa 5372static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5373 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5374 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5375 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5376 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5378 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5379 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5380 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5381 { } /* end */
5382};
5383
bec15c3a
TI
5384/* update HP, line and mono out pins according to the master switch */
5385static void alc260_hp_master_update(struct hda_codec *codec,
5386 hda_nid_t hp, hda_nid_t line,
5387 hda_nid_t mono)
5388{
5389 struct alc_spec *spec = codec->spec;
5390 unsigned int val = spec->master_sw ? PIN_HP : 0;
5391 /* change HP and line-out pins */
30cde0aa 5392 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5393 val);
30cde0aa 5394 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5395 val);
5396 /* mono (speaker) depending on the HP jack sense */
5397 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5398 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5399 val);
5400}
5401
5402static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5403 struct snd_ctl_elem_value *ucontrol)
5404{
5405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5406 struct alc_spec *spec = codec->spec;
5407 *ucontrol->value.integer.value = spec->master_sw;
5408 return 0;
5409}
5410
5411static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5412 struct snd_ctl_elem_value *ucontrol)
5413{
5414 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5415 struct alc_spec *spec = codec->spec;
5416 int val = !!*ucontrol->value.integer.value;
5417 hda_nid_t hp, line, mono;
5418
5419 if (val == spec->master_sw)
5420 return 0;
5421 spec->master_sw = val;
5422 hp = (kcontrol->private_value >> 16) & 0xff;
5423 line = (kcontrol->private_value >> 8) & 0xff;
5424 mono = kcontrol->private_value & 0xff;
5425 alc260_hp_master_update(codec, hp, line, mono);
5426 return 1;
5427}
5428
5429static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5430 {
5431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5432 .name = "Master Playback Switch",
5b0cb1d8 5433 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5434 .info = snd_ctl_boolean_mono_info,
5435 .get = alc260_hp_master_sw_get,
5436 .put = alc260_hp_master_sw_put,
5437 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5438 },
5439 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5440 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5441 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5442 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5443 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5444 HDA_OUTPUT),
5445 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5446 { } /* end */
5447};
5448
5449static struct hda_verb alc260_hp_unsol_verbs[] = {
5450 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5451 {},
5452};
5453
5454static void alc260_hp_automute(struct hda_codec *codec)
5455{
5456 struct alc_spec *spec = codec->spec;
bec15c3a 5457
864f92be 5458 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5459 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5460}
5461
5462static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5463{
5464 if ((res >> 26) == ALC880_HP_EVENT)
5465 alc260_hp_automute(codec);
5466}
5467
df694daa 5468static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5469 {
5470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5471 .name = "Master Playback Switch",
5b0cb1d8 5472 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5473 .info = snd_ctl_boolean_mono_info,
5474 .get = alc260_hp_master_sw_get,
5475 .put = alc260_hp_master_sw_put,
30cde0aa 5476 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5477 },
df694daa
KY
5478 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5479 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5480 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5481 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5482 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5484 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5485 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5486 { } /* end */
5487};
5488
3f878308
KY
5489static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5490 .ops = &snd_hda_bind_vol,
5491 .values = {
5492 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5493 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5494 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5495 0
5496 },
5497};
5498
5499static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5500 .ops = &snd_hda_bind_sw,
5501 .values = {
5502 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5503 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5504 0
5505 },
5506};
5507
5508static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5509 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5510 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5511 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5513 { } /* end */
5514};
5515
bec15c3a
TI
5516static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5517 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5518 {},
5519};
5520
5521static void alc260_hp_3013_automute(struct hda_codec *codec)
5522{
5523 struct alc_spec *spec = codec->spec;
bec15c3a 5524
864f92be 5525 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5526 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5527}
5528
5529static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5530 unsigned int res)
5531{
5532 if ((res >> 26) == ALC880_HP_EVENT)
5533 alc260_hp_3013_automute(codec);
5534}
5535
3f878308
KY
5536static void alc260_hp_3012_automute(struct hda_codec *codec)
5537{
864f92be 5538 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5539
3f878308
KY
5540 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5541 bits);
5542 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5543 bits);
5544 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5545 bits);
5546}
5547
5548static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5549 unsigned int res)
5550{
5551 if ((res >> 26) == ALC880_HP_EVENT)
5552 alc260_hp_3012_automute(codec);
5553}
5554
5555/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5556 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5557 */
c8b6bf9b 5558static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5559 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5560 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5561 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5562 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5563 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5564 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5565 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5566 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5567 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5568 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5569 { } /* end */
5570};
5571
a1e8d2da
JW
5572/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5573 * versions of the ALC260 don't act on requests to enable mic bias from NID
5574 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5575 * datasheet doesn't mention this restriction. At this stage it's not clear
5576 * whether this behaviour is intentional or is a hardware bug in chip
5577 * revisions available in early 2006. Therefore for now allow the
5578 * "Headphone Jack Mode" control to span all choices, but if it turns out
5579 * that the lack of mic bias for this NID is intentional we could change the
5580 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5581 *
5582 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5583 * don't appear to make the mic bias available from the "line" jack, even
5584 * though the NID used for this jack (0x14) can supply it. The theory is
5585 * that perhaps Acer have included blocking capacitors between the ALC260
5586 * and the output jack. If this turns out to be the case for all such
5587 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5588 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5589 *
5590 * The C20x Tablet series have a mono internal speaker which is controlled
5591 * via the chip's Mono sum widget and pin complex, so include the necessary
5592 * controls for such models. On models without a "mono speaker" the control
5593 * won't do anything.
a1e8d2da 5594 */
0bfc90e9
JW
5595static struct snd_kcontrol_new alc260_acer_mixer[] = {
5596 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5597 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5598 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5599 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5600 HDA_OUTPUT),
31bffaa9 5601 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5602 HDA_INPUT),
0bfc90e9
JW
5603 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5604 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5605 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5606 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5607 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5608 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5609 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5610 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5611 { } /* end */
5612};
5613
cc959489
MS
5614/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5615 */
5616static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5617 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5618 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5619 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5620 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5621 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5622 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5623 { } /* end */
5624};
5625
bc9f98a9
KY
5626/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5627 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5628 */
5629static struct snd_kcontrol_new alc260_will_mixer[] = {
5630 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5631 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5633 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5634 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5635 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5636 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5637 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5638 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5639 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5640 { } /* end */
5641};
5642
5643/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5644 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5645 */
5646static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5647 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5648 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5650 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5651 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5652 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5653 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5654 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5655 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5656 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5657 { } /* end */
5658};
5659
df694daa
KY
5660/*
5661 * initialization verbs
5662 */
1da177e4
LT
5663static struct hda_verb alc260_init_verbs[] = {
5664 /* Line In pin widget for input */
05acb863 5665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5666 /* CD pin widget for input */
05acb863 5667 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5668 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5669 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5670 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5671 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5672 /* LINE-2 is used for line-out in rear */
05acb863 5673 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5674 /* select line-out */
fd56f2db 5675 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5676 /* LINE-OUT pin */
05acb863 5677 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5678 /* enable HP */
05acb863 5679 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5680 /* enable Mono */
05acb863
TI
5681 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5682 /* mute capture amp left and right */
16ded525 5683 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5684 /* set connection select to line in (default select for this ADC) */
5685 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5686 /* mute capture amp left and right */
5687 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5688 /* set connection select to line in (default select for this ADC) */
5689 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5690 /* set vol=0 Line-Out mixer amp left and right */
5691 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5692 /* unmute pin widget amp left and right (no gain on this amp) */
5693 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5694 /* set vol=0 HP mixer amp left and right */
5695 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5696 /* unmute pin widget amp left and right (no gain on this amp) */
5697 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5698 /* set vol=0 Mono mixer amp left and right */
5699 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5700 /* unmute pin widget amp left and right (no gain on this amp) */
5701 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5702 /* unmute LINE-2 out pin */
5703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5704 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5705 * Line In 2 = 0x03
5706 */
cb53c626
TI
5707 /* mute analog inputs */
5708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5713 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5714 /* mute Front out path */
5715 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5716 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5717 /* mute Headphone out path */
5718 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5719 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5720 /* mute Mono out path */
5721 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5723 { }
5724};
5725
474167d6 5726#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5727static struct hda_verb alc260_hp_init_verbs[] = {
5728 /* Headphone and output */
5729 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5730 /* mono output */
5731 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5732 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5733 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5734 /* Mic2 (front panel) pin widget for input and vref at 80% */
5735 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5736 /* Line In pin widget for input */
5737 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5738 /* Line-2 pin widget for output */
5739 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5740 /* CD pin widget for input */
5741 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5742 /* unmute amp left and right */
5743 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5744 /* set connection select to line in (default select for this ADC) */
5745 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5746 /* unmute Line-Out mixer amp left and right (volume = 0) */
5747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5748 /* mute pin widget amp left and right (no gain on this amp) */
5749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5750 /* unmute HP mixer amp left and right (volume = 0) */
5751 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5752 /* mute pin widget amp left and right (no gain on this amp) */
5753 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5754 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5755 * Line In 2 = 0x03
5756 */
cb53c626
TI
5757 /* mute analog inputs */
5758 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5759 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5760 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5761 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5762 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5763 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5764 /* Unmute Front out path */
5765 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5766 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5767 /* Unmute Headphone out path */
5768 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5769 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5770 /* Unmute Mono out path */
5771 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5772 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5773 { }
5774};
474167d6 5775#endif
df694daa
KY
5776
5777static struct hda_verb alc260_hp_3013_init_verbs[] = {
5778 /* Line out and output */
5779 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5780 /* mono output */
5781 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5782 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5783 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5784 /* Mic2 (front panel) pin widget for input and vref at 80% */
5785 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5786 /* Line In pin widget for input */
5787 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5788 /* Headphone pin widget for output */
5789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5790 /* CD pin widget for input */
5791 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5792 /* unmute amp left and right */
5793 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5794 /* set connection select to line in (default select for this ADC) */
5795 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5796 /* unmute Line-Out mixer amp left and right (volume = 0) */
5797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5798 /* mute pin widget amp left and right (no gain on this amp) */
5799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5800 /* unmute HP mixer amp left and right (volume = 0) */
5801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5802 /* mute pin widget amp left and right (no gain on this amp) */
5803 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5804 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5805 * Line In 2 = 0x03
5806 */
cb53c626
TI
5807 /* mute analog inputs */
5808 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5809 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5810 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5811 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5813 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5814 /* Unmute Front out path */
5815 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5816 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5817 /* Unmute Headphone out path */
5818 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5820 /* Unmute Mono out path */
5821 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5822 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5823 { }
5824};
5825
a9430dd8 5826/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5827 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5828 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5829 */
5830static struct hda_verb alc260_fujitsu_init_verbs[] = {
5831 /* Disable all GPIOs */
5832 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5833 /* Internal speaker is connected to headphone pin */
5834 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5835 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5836 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5837 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5838 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5839 /* Ensure all other unused pins are disabled and muted. */
5840 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5842 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5843 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5844 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5845 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5848
5849 /* Disable digital (SPDIF) pins */
5850 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5851 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5852
ea1fb29a 5853 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5854 * when acting as an output.
5855 */
5856 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5857
f7ace40d 5858 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5859 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5861 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5862 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5864 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5865 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5866 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5867 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5868
f7ace40d
JW
5869 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5870 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5871 /* Unmute Line1 pin widget output buffer since it starts as an output.
5872 * If the pin mode is changed by the user the pin mode control will
5873 * take care of enabling the pin's input/output buffers as needed.
5874 * Therefore there's no need to enable the input buffer at this
5875 * stage.
cdcd9268 5876 */
f7ace40d 5877 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5878 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5879 * mixer ctrl)
5880 */
f7ace40d
JW
5881 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5882
5883 /* Mute capture amp left and right */
5884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5885 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5886 * in (on mic1 pin)
5887 */
5888 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5889
5890 /* Do the same for the second ADC: mute capture input amp and
5891 * set ADC connection to line in (on mic1 pin)
5892 */
5893 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5894 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5895
5896 /* Mute all inputs to mixer widget (even unconnected ones) */
5897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5900 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5901 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5902 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5903 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5904 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5905
5906 { }
a9430dd8
JW
5907};
5908
0bfc90e9
JW
5909/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5910 * similar laptops (adapted from Fujitsu init verbs).
5911 */
5912static struct hda_verb alc260_acer_init_verbs[] = {
5913 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5914 * the headphone jack. Turn this on and rely on the standard mute
5915 * methods whenever the user wants to turn these outputs off.
5916 */
5917 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5918 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5919 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5920 /* Internal speaker/Headphone jack is connected to Line-out pin */
5921 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5922 /* Internal microphone/Mic jack is connected to Mic1 pin */
5923 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5924 /* Line In jack is connected to Line1 pin */
5925 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5926 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5927 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5928 /* Ensure all other unused pins are disabled and muted. */
5929 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5930 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5931 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5932 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5935 /* Disable digital (SPDIF) pins */
5936 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5937 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5938
ea1fb29a 5939 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5940 * bus when acting as outputs.
5941 */
5942 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5943 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5944
5945 /* Start with output sum widgets muted and their output gains at min */
5946 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5947 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5949 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5950 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5951 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5952 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5953 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5954 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5955
f12ab1e0
TI
5956 /* Unmute Line-out pin widget amp left and right
5957 * (no equiv mixer ctrl)
5958 */
0bfc90e9 5959 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5960 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5961 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5962 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5963 * inputs. If the pin mode is changed by the user the pin mode control
5964 * will take care of enabling the pin's input/output buffers as needed.
5965 * Therefore there's no need to enable the input buffer at this
5966 * stage.
5967 */
5968 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5969 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5970
5971 /* Mute capture amp left and right */
5972 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5973 /* Set ADC connection select to match default mixer setting - mic
5974 * (on mic1 pin)
5975 */
5976 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5977
5978 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5979 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5980 */
5981 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5982 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5983
5984 /* Mute all inputs to mixer widget (even unconnected ones) */
5985 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5986 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5987 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5988 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5990 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5993
5994 { }
5995};
5996
cc959489
MS
5997/* Initialisation sequence for Maxdata Favorit 100XS
5998 * (adapted from Acer init verbs).
5999 */
6000static struct hda_verb alc260_favorit100_init_verbs[] = {
6001 /* GPIO 0 enables the output jack.
6002 * Turn this on and rely on the standard mute
6003 * methods whenever the user wants to turn these outputs off.
6004 */
6005 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6006 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6007 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6008 /* Line/Mic input jack is connected to Mic1 pin */
6009 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6010 /* Ensure all other unused pins are disabled and muted. */
6011 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6012 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6013 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6014 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6015 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6016 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6017 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6018 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6021 /* Disable digital (SPDIF) pins */
6022 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6023 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6024
6025 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6026 * bus when acting as outputs.
6027 */
6028 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6029 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6030
6031 /* Start with output sum widgets muted and their output gains at min */
6032 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6033 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6034 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6035 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6036 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6037 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6038 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6039 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6040 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6041
6042 /* Unmute Line-out pin widget amp left and right
6043 * (no equiv mixer ctrl)
6044 */
6045 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6046 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6047 * inputs. If the pin mode is changed by the user the pin mode control
6048 * will take care of enabling the pin's input/output buffers as needed.
6049 * Therefore there's no need to enable the input buffer at this
6050 * stage.
6051 */
6052 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6053
6054 /* Mute capture amp left and right */
6055 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6056 /* Set ADC connection select to match default mixer setting - mic
6057 * (on mic1 pin)
6058 */
6059 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6060
6061 /* Do similar with the second ADC: mute capture input amp and
6062 * set ADC connection to mic to match ALSA's default state.
6063 */
6064 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6065 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6066
6067 /* Mute all inputs to mixer widget (even unconnected ones) */
6068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6072 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6074 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6076
6077 { }
6078};
6079
bc9f98a9
KY
6080static struct hda_verb alc260_will_verbs[] = {
6081 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6082 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6083 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6084 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6085 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6086 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6087 {}
6088};
6089
6090static struct hda_verb alc260_replacer_672v_verbs[] = {
6091 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6092 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6093 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6094
6095 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6096 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6097 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6098
6099 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6100 {}
6101};
6102
6103/* toggle speaker-output according to the hp-jack state */
6104static void alc260_replacer_672v_automute(struct hda_codec *codec)
6105{
6106 unsigned int present;
6107
6108 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6109 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6110 if (present) {
82beb8fd
TI
6111 snd_hda_codec_write_cache(codec, 0x01, 0,
6112 AC_VERB_SET_GPIO_DATA, 1);
6113 snd_hda_codec_write_cache(codec, 0x0f, 0,
6114 AC_VERB_SET_PIN_WIDGET_CONTROL,
6115 PIN_HP);
bc9f98a9 6116 } else {
82beb8fd
TI
6117 snd_hda_codec_write_cache(codec, 0x01, 0,
6118 AC_VERB_SET_GPIO_DATA, 0);
6119 snd_hda_codec_write_cache(codec, 0x0f, 0,
6120 AC_VERB_SET_PIN_WIDGET_CONTROL,
6121 PIN_OUT);
bc9f98a9
KY
6122 }
6123}
6124
6125static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6126 unsigned int res)
6127{
6128 if ((res >> 26) == ALC880_HP_EVENT)
6129 alc260_replacer_672v_automute(codec);
6130}
6131
3f878308
KY
6132static struct hda_verb alc260_hp_dc7600_verbs[] = {
6133 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6134 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6135 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6136 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6137 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6138 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6140 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6141 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6142 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6143 {}
6144};
6145
7cf51e48
JW
6146/* Test configuration for debugging, modelled after the ALC880 test
6147 * configuration.
6148 */
6149#ifdef CONFIG_SND_DEBUG
6150static hda_nid_t alc260_test_dac_nids[1] = {
6151 0x02,
6152};
6153static hda_nid_t alc260_test_adc_nids[2] = {
6154 0x04, 0x05,
6155};
a1e8d2da 6156/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6157 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6158 * is NID 0x04.
17e7aec6 6159 */
a1e8d2da
JW
6160static struct hda_input_mux alc260_test_capture_sources[2] = {
6161 {
6162 .num_items = 7,
6163 .items = {
6164 { "MIC1 pin", 0x0 },
6165 { "MIC2 pin", 0x1 },
6166 { "LINE1 pin", 0x2 },
6167 { "LINE2 pin", 0x3 },
6168 { "CD pin", 0x4 },
6169 { "LINE-OUT pin", 0x5 },
6170 { "HP-OUT pin", 0x6 },
6171 },
6172 },
6173 {
6174 .num_items = 8,
6175 .items = {
6176 { "MIC1 pin", 0x0 },
6177 { "MIC2 pin", 0x1 },
6178 { "LINE1 pin", 0x2 },
6179 { "LINE2 pin", 0x3 },
6180 { "CD pin", 0x4 },
6181 { "Mixer", 0x5 },
6182 { "LINE-OUT pin", 0x6 },
6183 { "HP-OUT pin", 0x7 },
6184 },
7cf51e48
JW
6185 },
6186};
6187static struct snd_kcontrol_new alc260_test_mixer[] = {
6188 /* Output driver widgets */
6189 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6190 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6191 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6192 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6193 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6194 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6195
a1e8d2da
JW
6196 /* Modes for retasking pin widgets
6197 * Note: the ALC260 doesn't seem to act on requests to enable mic
6198 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6199 * mention this restriction. At this stage it's not clear whether
6200 * this behaviour is intentional or is a hardware bug in chip
6201 * revisions available at least up until early 2006. Therefore for
6202 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6203 * choices, but if it turns out that the lack of mic bias for these
6204 * NIDs is intentional we could change their modes from
6205 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6206 */
7cf51e48
JW
6207 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6208 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6209 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6210 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6211 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6212 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6213
6214 /* Loopback mixer controls */
6215 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6216 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6217 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6218 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6219 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6220 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6221 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6222 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6223 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6224 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6225 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6226 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6227 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6228 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6229
6230 /* Controls for GPIO pins, assuming they are configured as outputs */
6231 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6232 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6233 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6234 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6235
92621f13
JW
6236 /* Switches to allow the digital IO pins to be enabled. The datasheet
6237 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6238 * make this output available should provide clarification.
92621f13
JW
6239 */
6240 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6241 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6242
f8225f6d
JW
6243 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6244 * this output to turn on an external amplifier.
6245 */
6246 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6247 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6248
7cf51e48
JW
6249 { } /* end */
6250};
6251static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6252 /* Enable all GPIOs as outputs with an initial value of 0 */
6253 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6254 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6255 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6256
7cf51e48
JW
6257 /* Enable retasking pins as output, initially without power amp */
6258 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6259 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6261 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6262 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6263 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6264
92621f13
JW
6265 /* Disable digital (SPDIF) pins initially, but users can enable
6266 * them via a mixer switch. In the case of SPDIF-out, this initverb
6267 * payload also sets the generation to 0, output to be in "consumer"
6268 * PCM format, copyright asserted, no pre-emphasis and no validity
6269 * control.
6270 */
7cf51e48
JW
6271 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6272 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6273
ea1fb29a 6274 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6275 * OUT1 sum bus when acting as an output.
6276 */
6277 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6278 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6279 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6280 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6281
6282 /* Start with output sum widgets muted and their output gains at min */
6283 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6284 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6289 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6290 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6291 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6292
cdcd9268
JW
6293 /* Unmute retasking pin widget output buffers since the default
6294 * state appears to be output. As the pin mode is changed by the
6295 * user the pin mode control will take care of enabling the pin's
6296 * input/output buffers as needed.
6297 */
7cf51e48
JW
6298 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6299 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6301 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6302 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6303 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6304 /* Also unmute the mono-out pin widget */
6305 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6306
7cf51e48
JW
6307 /* Mute capture amp left and right */
6308 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6309 /* Set ADC connection select to match default mixer setting (mic1
6310 * pin)
7cf51e48
JW
6311 */
6312 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6313
6314 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6315 * set ADC connection to mic1 pin
7cf51e48
JW
6316 */
6317 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6318 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6319
6320 /* Mute all inputs to mixer widget (even unconnected ones) */
6321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6329
6330 { }
6331};
6332#endif
6333
6330079f
TI
6334#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6335#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6336
a3bcba38
TI
6337#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6338#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6339
df694daa
KY
6340/*
6341 * for BIOS auto-configuration
6342 */
16ded525 6343
df694daa 6344static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6345 const char *pfx, int *vol_bits)
df694daa
KY
6346{
6347 hda_nid_t nid_vol;
6348 unsigned long vol_val, sw_val;
df694daa
KY
6349 int err;
6350
6351 if (nid >= 0x0f && nid < 0x11) {
6352 nid_vol = nid - 0x7;
6353 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6354 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6355 } else if (nid == 0x11) {
6356 nid_vol = nid - 0x7;
6357 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6358 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6359 } else if (nid >= 0x12 && nid <= 0x15) {
6360 nid_vol = 0x08;
6361 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6362 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6363 } else
6364 return 0; /* N/A */
ea1fb29a 6365
863b4518
TI
6366 if (!(*vol_bits & (1 << nid_vol))) {
6367 /* first control for the volume widget */
0afe5f89 6368 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6369 if (err < 0)
6370 return err;
6371 *vol_bits |= (1 << nid_vol);
6372 }
0afe5f89 6373 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6374 if (err < 0)
df694daa
KY
6375 return err;
6376 return 1;
6377}
6378
6379/* add playback controls from the parsed DAC table */
6380static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6381 const struct auto_pin_cfg *cfg)
6382{
6383 hda_nid_t nid;
6384 int err;
863b4518 6385 int vols = 0;
df694daa
KY
6386
6387 spec->multiout.num_dacs = 1;
6388 spec->multiout.dac_nids = spec->private_dac_nids;
6389 spec->multiout.dac_nids[0] = 0x02;
6390
6391 nid = cfg->line_out_pins[0];
6392 if (nid) {
23112d6d
TI
6393 const char *pfx;
6394 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6395 pfx = "Master";
6396 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6397 pfx = "Speaker";
6398 else
6399 pfx = "Front";
6400 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6401 if (err < 0)
6402 return err;
6403 }
6404
82bc955f 6405 nid = cfg->speaker_pins[0];
df694daa 6406 if (nid) {
863b4518 6407 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6408 if (err < 0)
6409 return err;
6410 }
6411
eb06ed8f 6412 nid = cfg->hp_pins[0];
df694daa 6413 if (nid) {
863b4518
TI
6414 err = alc260_add_playback_controls(spec, nid, "Headphone",
6415 &vols);
df694daa
KY
6416 if (err < 0)
6417 return err;
6418 }
f12ab1e0 6419 return 0;
df694daa
KY
6420}
6421
6422/* create playback/capture controls for input pins */
05f5f477 6423static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6424 const struct auto_pin_cfg *cfg)
6425{
05f5f477 6426 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6427}
6428
6429static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6430 hda_nid_t nid, int pin_type,
6431 int sel_idx)
6432{
f6c7e546 6433 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6434 /* need the manual connection? */
6435 if (nid >= 0x12) {
6436 int idx = nid - 0x12;
6437 snd_hda_codec_write(codec, idx + 0x0b, 0,
6438 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6439 }
6440}
6441
6442static void alc260_auto_init_multi_out(struct hda_codec *codec)
6443{
6444 struct alc_spec *spec = codec->spec;
6445 hda_nid_t nid;
6446
f12ab1e0 6447 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6448 if (nid) {
6449 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6450 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6451 }
ea1fb29a 6452
82bc955f 6453 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6454 if (nid)
6455 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6456
eb06ed8f 6457 nid = spec->autocfg.hp_pins[0];
df694daa 6458 if (nid)
baba8ee9 6459 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6460}
df694daa
KY
6461
6462#define ALC260_PIN_CD_NID 0x16
6463static void alc260_auto_init_analog_input(struct hda_codec *codec)
6464{
6465 struct alc_spec *spec = codec->spec;
6466 int i;
6467
6468 for (i = 0; i < AUTO_PIN_LAST; i++) {
6469 hda_nid_t nid = spec->autocfg.input_pins[i];
6470 if (nid >= 0x12) {
23f0c048 6471 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6472 if (nid != ALC260_PIN_CD_NID &&
6473 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6474 snd_hda_codec_write(codec, nid, 0,
6475 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6476 AMP_OUT_MUTE);
6477 }
6478 }
6479}
6480
6481/*
6482 * generic initialization of ADC, input mixers and output mixers
6483 */
6484static struct hda_verb alc260_volume_init_verbs[] = {
6485 /*
6486 * Unmute ADC0-1 and set the default input to mic-in
6487 */
6488 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6489 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6490 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6491 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6492
df694daa
KY
6493 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6494 * mixer widget
f12ab1e0
TI
6495 * Note: PASD motherboards uses the Line In 2 as the input for
6496 * front panel mic (mic 2)
df694daa
KY
6497 */
6498 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6499 /* mute analog inputs */
6500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6505
6506 /*
6507 * Set up output mixers (0x08 - 0x0a)
6508 */
6509 /* set vol=0 to output mixers */
6510 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6513 /* set up input amps for analog loopback */
6514 /* Amp Indices: DAC = 0, mixer = 1 */
6515 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6519 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6520 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6521
df694daa
KY
6522 { }
6523};
6524
6525static int alc260_parse_auto_config(struct hda_codec *codec)
6526{
6527 struct alc_spec *spec = codec->spec;
df694daa
KY
6528 int err;
6529 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6530
f12ab1e0
TI
6531 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6532 alc260_ignore);
6533 if (err < 0)
df694daa 6534 return err;
f12ab1e0
TI
6535 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6536 if (err < 0)
4a471b7d 6537 return err;
603c4019 6538 if (!spec->kctls.list)
df694daa 6539 return 0; /* can't find valid BIOS pin config */
05f5f477 6540 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6541 if (err < 0)
df694daa
KY
6542 return err;
6543
6544 spec->multiout.max_channels = 2;
6545
0852d7a6 6546 if (spec->autocfg.dig_outs)
df694daa 6547 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6548 if (spec->kctls.list)
d88897ea 6549 add_mixer(spec, spec->kctls.list);
df694daa 6550
d88897ea 6551 add_verb(spec, alc260_volume_init_verbs);
df694daa 6552
a1e8d2da 6553 spec->num_mux_defs = 1;
61b9b9b1 6554 spec->input_mux = &spec->private_imux[0];
df694daa 6555
6227cdce 6556 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6557
df694daa
KY
6558 return 1;
6559}
6560
ae6b813a
TI
6561/* additional initialization for auto-configuration model */
6562static void alc260_auto_init(struct hda_codec *codec)
df694daa 6563{
f6c7e546 6564 struct alc_spec *spec = codec->spec;
df694daa
KY
6565 alc260_auto_init_multi_out(codec);
6566 alc260_auto_init_analog_input(codec);
f6c7e546 6567 if (spec->unsol_event)
7fb0d78f 6568 alc_inithook(codec);
df694daa
KY
6569}
6570
cb53c626
TI
6571#ifdef CONFIG_SND_HDA_POWER_SAVE
6572static struct hda_amp_list alc260_loopbacks[] = {
6573 { 0x07, HDA_INPUT, 0 },
6574 { 0x07, HDA_INPUT, 1 },
6575 { 0x07, HDA_INPUT, 2 },
6576 { 0x07, HDA_INPUT, 3 },
6577 { 0x07, HDA_INPUT, 4 },
6578 { } /* end */
6579};
6580#endif
6581
df694daa
KY
6582/*
6583 * ALC260 configurations
6584 */
f5fcc13c
TI
6585static const char *alc260_models[ALC260_MODEL_LAST] = {
6586 [ALC260_BASIC] = "basic",
6587 [ALC260_HP] = "hp",
6588 [ALC260_HP_3013] = "hp-3013",
2922c9af 6589 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6590 [ALC260_FUJITSU_S702X] = "fujitsu",
6591 [ALC260_ACER] = "acer",
bc9f98a9
KY
6592 [ALC260_WILL] = "will",
6593 [ALC260_REPLACER_672V] = "replacer",
cc959489 6594 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6595#ifdef CONFIG_SND_DEBUG
f5fcc13c 6596 [ALC260_TEST] = "test",
7cf51e48 6597#endif
f5fcc13c
TI
6598 [ALC260_AUTO] = "auto",
6599};
6600
6601static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6602 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6603 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6604 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6605 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6606 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6607 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6608 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6609 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6610 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6611 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6612 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6613 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6614 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6615 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6616 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6617 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6618 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6619 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6620 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6621 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6622 {}
6623};
6624
6625static struct alc_config_preset alc260_presets[] = {
6626 [ALC260_BASIC] = {
6627 .mixers = { alc260_base_output_mixer,
45bdd1c1 6628 alc260_input_mixer },
df694daa
KY
6629 .init_verbs = { alc260_init_verbs },
6630 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6631 .dac_nids = alc260_dac_nids,
f9e336f6 6632 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6633 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6634 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6635 .channel_mode = alc260_modes,
6636 .input_mux = &alc260_capture_source,
6637 },
6638 [ALC260_HP] = {
bec15c3a 6639 .mixers = { alc260_hp_output_mixer,
f9e336f6 6640 alc260_input_mixer },
bec15c3a
TI
6641 .init_verbs = { alc260_init_verbs,
6642 alc260_hp_unsol_verbs },
df694daa
KY
6643 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6644 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6645 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6646 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6647 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6648 .channel_mode = alc260_modes,
6649 .input_mux = &alc260_capture_source,
bec15c3a
TI
6650 .unsol_event = alc260_hp_unsol_event,
6651 .init_hook = alc260_hp_automute,
df694daa 6652 },
3f878308
KY
6653 [ALC260_HP_DC7600] = {
6654 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6655 alc260_input_mixer },
3f878308
KY
6656 .init_verbs = { alc260_init_verbs,
6657 alc260_hp_dc7600_verbs },
6658 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6659 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6660 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6661 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6662 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6663 .channel_mode = alc260_modes,
6664 .input_mux = &alc260_capture_source,
6665 .unsol_event = alc260_hp_3012_unsol_event,
6666 .init_hook = alc260_hp_3012_automute,
6667 },
df694daa
KY
6668 [ALC260_HP_3013] = {
6669 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6670 alc260_input_mixer },
bec15c3a
TI
6671 .init_verbs = { alc260_hp_3013_init_verbs,
6672 alc260_hp_3013_unsol_verbs },
df694daa
KY
6673 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6674 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6675 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6676 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6677 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6678 .channel_mode = alc260_modes,
6679 .input_mux = &alc260_capture_source,
bec15c3a
TI
6680 .unsol_event = alc260_hp_3013_unsol_event,
6681 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6682 },
6683 [ALC260_FUJITSU_S702X] = {
f9e336f6 6684 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6685 .init_verbs = { alc260_fujitsu_init_verbs },
6686 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6687 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6688 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6689 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6690 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6691 .channel_mode = alc260_modes,
a1e8d2da
JW
6692 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6693 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6694 },
0bfc90e9 6695 [ALC260_ACER] = {
f9e336f6 6696 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6697 .init_verbs = { alc260_acer_init_verbs },
6698 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6699 .dac_nids = alc260_dac_nids,
6700 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6701 .adc_nids = alc260_dual_adc_nids,
6702 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6703 .channel_mode = alc260_modes,
a1e8d2da
JW
6704 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6705 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6706 },
cc959489
MS
6707 [ALC260_FAVORIT100] = {
6708 .mixers = { alc260_favorit100_mixer },
6709 .init_verbs = { alc260_favorit100_init_verbs },
6710 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6711 .dac_nids = alc260_dac_nids,
6712 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6713 .adc_nids = alc260_dual_adc_nids,
6714 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6715 .channel_mode = alc260_modes,
6716 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6717 .input_mux = alc260_favorit100_capture_sources,
6718 },
bc9f98a9 6719 [ALC260_WILL] = {
f9e336f6 6720 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6721 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6722 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6723 .dac_nids = alc260_dac_nids,
6724 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6725 .adc_nids = alc260_adc_nids,
6726 .dig_out_nid = ALC260_DIGOUT_NID,
6727 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6728 .channel_mode = alc260_modes,
6729 .input_mux = &alc260_capture_source,
6730 },
6731 [ALC260_REPLACER_672V] = {
f9e336f6 6732 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6733 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6734 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6735 .dac_nids = alc260_dac_nids,
6736 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6737 .adc_nids = alc260_adc_nids,
6738 .dig_out_nid = ALC260_DIGOUT_NID,
6739 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6740 .channel_mode = alc260_modes,
6741 .input_mux = &alc260_capture_source,
6742 .unsol_event = alc260_replacer_672v_unsol_event,
6743 .init_hook = alc260_replacer_672v_automute,
6744 },
7cf51e48
JW
6745#ifdef CONFIG_SND_DEBUG
6746 [ALC260_TEST] = {
f9e336f6 6747 .mixers = { alc260_test_mixer },
7cf51e48
JW
6748 .init_verbs = { alc260_test_init_verbs },
6749 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6750 .dac_nids = alc260_test_dac_nids,
6751 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6752 .adc_nids = alc260_test_adc_nids,
6753 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6754 .channel_mode = alc260_modes,
a1e8d2da
JW
6755 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6756 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6757 },
6758#endif
df694daa
KY
6759};
6760
6761static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6762{
6763 struct alc_spec *spec;
df694daa 6764 int err, board_config;
1da177e4 6765
e560d8d8 6766 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6767 if (spec == NULL)
6768 return -ENOMEM;
6769
6770 codec->spec = spec;
6771
f5fcc13c
TI
6772 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6773 alc260_models,
6774 alc260_cfg_tbl);
6775 if (board_config < 0) {
9a11f1aa 6776 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6777 codec->chip_name);
df694daa 6778 board_config = ALC260_AUTO;
16ded525 6779 }
1da177e4 6780
df694daa
KY
6781 if (board_config == ALC260_AUTO) {
6782 /* automatic parse from the BIOS config */
6783 err = alc260_parse_auto_config(codec);
6784 if (err < 0) {
6785 alc_free(codec);
6786 return err;
f12ab1e0 6787 } else if (!err) {
9c7f852e
TI
6788 printk(KERN_INFO
6789 "hda_codec: Cannot set up configuration "
6790 "from BIOS. Using base mode...\n");
df694daa
KY
6791 board_config = ALC260_BASIC;
6792 }
a9430dd8 6793 }
e9edcee0 6794
680cd536
KK
6795 err = snd_hda_attach_beep_device(codec, 0x1);
6796 if (err < 0) {
6797 alc_free(codec);
6798 return err;
6799 }
6800
df694daa 6801 if (board_config != ALC260_AUTO)
e9c364c0 6802 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 6803
1da177e4
LT
6804 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6805 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6806
a3bcba38
TI
6807 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6808 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6809
4ef0ef19
TI
6810 if (!spec->adc_nids && spec->input_mux) {
6811 /* check whether NID 0x04 is valid */
6812 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 6813 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
6814 /* get type */
6815 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6816 spec->adc_nids = alc260_adc_nids_alt;
6817 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6818 } else {
6819 spec->adc_nids = alc260_adc_nids;
6820 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6821 }
6822 }
b59bdf3b 6823 set_capture_mixer(codec);
45bdd1c1 6824 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6825
2134ea4f
TI
6826 spec->vmaster_nid = 0x08;
6827
1da177e4 6828 codec->patch_ops = alc_patch_ops;
df694daa 6829 if (board_config == ALC260_AUTO)
ae6b813a 6830 spec->init_hook = alc260_auto_init;
cb53c626
TI
6831#ifdef CONFIG_SND_HDA_POWER_SAVE
6832 if (!spec->loopback.amplist)
6833 spec->loopback.amplist = alc260_loopbacks;
6834#endif
1da177e4
LT
6835
6836 return 0;
6837}
6838
e9edcee0 6839
1da177e4 6840/*
4953550a 6841 * ALC882/883/885/888/889 support
1da177e4
LT
6842 *
6843 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6844 * configuration. Each pin widget can choose any input DACs and a mixer.
6845 * Each ADC is connected from a mixer of all inputs. This makes possible
6846 * 6-channel independent captures.
6847 *
6848 * In addition, an independent DAC for the multi-playback (not used in this
6849 * driver yet).
6850 */
df694daa
KY
6851#define ALC882_DIGOUT_NID 0x06
6852#define ALC882_DIGIN_NID 0x0a
4953550a
TI
6853#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6854#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6855#define ALC1200_DIGOUT_NID 0x10
6856
1da177e4 6857
d2a6d7dc 6858static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6859 { 8, NULL }
6860};
6861
4953550a 6862/* DACs */
1da177e4
LT
6863static hda_nid_t alc882_dac_nids[4] = {
6864 /* front, rear, clfe, rear_surr */
6865 0x02, 0x03, 0x04, 0x05
6866};
4953550a 6867#define alc883_dac_nids alc882_dac_nids
1da177e4 6868
4953550a 6869/* ADCs */
df694daa
KY
6870#define alc882_adc_nids alc880_adc_nids
6871#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
6872#define alc883_adc_nids alc882_adc_nids_alt
6873static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6874static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6875#define alc889_adc_nids alc880_adc_nids
1da177e4 6876
e1406348
TI
6877static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6878static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
6879#define alc883_capsrc_nids alc882_capsrc_nids_alt
6880static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6881#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 6882
1da177e4
LT
6883/* input MUX */
6884/* FIXME: should be a matrix-type input source selection */
6885
6886static struct hda_input_mux alc882_capture_source = {
6887 .num_items = 4,
6888 .items = {
6889 { "Mic", 0x0 },
6890 { "Front Mic", 0x1 },
6891 { "Line", 0x2 },
6892 { "CD", 0x4 },
6893 },
6894};
41d5545d 6895
4953550a
TI
6896#define alc883_capture_source alc882_capture_source
6897
87a8c370
JK
6898static struct hda_input_mux alc889_capture_source = {
6899 .num_items = 3,
6900 .items = {
6901 { "Front Mic", 0x0 },
6902 { "Mic", 0x3 },
6903 { "Line", 0x2 },
6904 },
6905};
6906
41d5545d
KS
6907static struct hda_input_mux mb5_capture_source = {
6908 .num_items = 3,
6909 .items = {
6910 { "Mic", 0x1 },
6911 { "Line", 0x2 },
6912 { "CD", 0x4 },
6913 },
6914};
6915
e458b1fa
LY
6916static struct hda_input_mux macmini3_capture_source = {
6917 .num_items = 2,
6918 .items = {
6919 { "Line", 0x2 },
6920 { "CD", 0x4 },
6921 },
6922};
6923
4953550a
TI
6924static struct hda_input_mux alc883_3stack_6ch_intel = {
6925 .num_items = 4,
6926 .items = {
6927 { "Mic", 0x1 },
6928 { "Front Mic", 0x0 },
6929 { "Line", 0x2 },
6930 { "CD", 0x4 },
6931 },
6932};
6933
6934static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6935 .num_items = 2,
6936 .items = {
6937 { "Mic", 0x1 },
6938 { "Line", 0x2 },
6939 },
6940};
6941
6942static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6943 .num_items = 4,
6944 .items = {
6945 { "Mic", 0x0 },
6946 { "iMic", 0x1 },
6947 { "Line", 0x2 },
6948 { "CD", 0x4 },
6949 },
6950};
6951
6952static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6953 .num_items = 2,
6954 .items = {
6955 { "Mic", 0x0 },
6956 { "Int Mic", 0x1 },
6957 },
6958};
6959
6960static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6961 .num_items = 3,
6962 .items = {
6963 { "Mic", 0x0 },
6964 { "Front Mic", 0x1 },
6965 { "Line", 0x4 },
6966 },
6967};
6968
6969static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6970 .num_items = 2,
6971 .items = {
6972 { "Mic", 0x0 },
6973 { "Line", 0x2 },
6974 },
6975};
6976
6977static struct hda_input_mux alc889A_mb31_capture_source = {
6978 .num_items = 2,
6979 .items = {
6980 { "Mic", 0x0 },
6981 /* Front Mic (0x01) unused */
6982 { "Line", 0x2 },
6983 /* Line 2 (0x03) unused */
af901ca1 6984 /* CD (0x04) unused? */
4953550a
TI
6985 },
6986};
6987
6988/*
6989 * 2ch mode
6990 */
6991static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6992 { 2, NULL }
6993};
6994
272a527c
KY
6995/*
6996 * 2ch mode
6997 */
6998static struct hda_verb alc882_3ST_ch2_init[] = {
6999 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7000 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7001 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7002 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7003 { } /* end */
7004};
7005
4953550a
TI
7006/*
7007 * 4ch mode
7008 */
7009static struct hda_verb alc882_3ST_ch4_init[] = {
7010 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7011 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7012 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7013 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7014 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7015 { } /* end */
7016};
7017
272a527c
KY
7018/*
7019 * 6ch mode
7020 */
7021static struct hda_verb alc882_3ST_ch6_init[] = {
7022 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7023 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7024 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7025 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7026 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7027 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7028 { } /* end */
7029};
7030
4953550a 7031static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7032 { 2, alc882_3ST_ch2_init },
4953550a 7033 { 4, alc882_3ST_ch4_init },
272a527c
KY
7034 { 6, alc882_3ST_ch6_init },
7035};
7036
4953550a
TI
7037#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7038
a65cc60f 7039/*
7040 * 2ch mode
7041 */
7042static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7043 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7044 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7045 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7046 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7047 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7048 { } /* end */
7049};
7050
7051/*
7052 * 4ch mode
7053 */
7054static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7055 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7056 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7057 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7058 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7059 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7060 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7061 { } /* end */
7062};
7063
7064/*
7065 * 6ch mode
7066 */
7067static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7068 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7069 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7070 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7071 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7072 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7073 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7074 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7075 { } /* end */
7076};
7077
7078static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7079 { 2, alc883_3ST_ch2_clevo_init },
7080 { 4, alc883_3ST_ch4_clevo_init },
7081 { 6, alc883_3ST_ch6_clevo_init },
7082};
7083
7084
df694daa
KY
7085/*
7086 * 6ch mode
7087 */
7088static struct hda_verb alc882_sixstack_ch6_init[] = {
7089 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7090 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7091 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7092 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7093 { } /* end */
7094};
7095
7096/*
7097 * 8ch mode
7098 */
7099static struct hda_verb alc882_sixstack_ch8_init[] = {
7100 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7101 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7102 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7103 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7104 { } /* end */
7105};
7106
7107static struct hda_channel_mode alc882_sixstack_modes[2] = {
7108 { 6, alc882_sixstack_ch6_init },
7109 { 8, alc882_sixstack_ch8_init },
7110};
7111
76e6f5a9
RH
7112
7113/* Macbook Air 2,1 */
7114
7115static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7116 { 2, NULL },
7117};
7118
87350ad0 7119/*
def319f9 7120 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7121 */
7122
7123/*
7124 * 2ch mode
7125 */
7126static struct hda_verb alc885_mbp_ch2_init[] = {
7127 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7128 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7129 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7130 { } /* end */
7131};
7132
7133/*
a3f730af 7134 * 4ch mode
87350ad0 7135 */
a3f730af 7136static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7137 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7138 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7140 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7141 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7142 { } /* end */
7143};
7144
a3f730af 7145static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7146 { 2, alc885_mbp_ch2_init },
a3f730af 7147 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7148};
7149
92b9de83
KS
7150/*
7151 * 2ch
7152 * Speakers/Woofer/HP = Front
7153 * LineIn = Input
7154 */
7155static struct hda_verb alc885_mb5_ch2_init[] = {
7156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7157 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7158 { } /* end */
7159};
7160
7161/*
7162 * 6ch mode
7163 * Speakers/HP = Front
7164 * Woofer = LFE
7165 * LineIn = Surround
7166 */
7167static struct hda_verb alc885_mb5_ch6_init[] = {
7168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7169 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7170 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7171 { } /* end */
7172};
7173
7174static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7175 { 2, alc885_mb5_ch2_init },
7176 { 6, alc885_mb5_ch6_init },
7177};
87350ad0 7178
d01aecdf 7179#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7180
7181/*
7182 * 2ch mode
7183 */
7184static struct hda_verb alc883_4ST_ch2_init[] = {
7185 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7186 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7187 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7188 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7189 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7190 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7191 { } /* end */
7192};
7193
7194/*
7195 * 4ch mode
7196 */
7197static struct hda_verb alc883_4ST_ch4_init[] = {
7198 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7199 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7200 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7201 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7202 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7203 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7204 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7205 { } /* end */
7206};
7207
7208/*
7209 * 6ch mode
7210 */
7211static struct hda_verb alc883_4ST_ch6_init[] = {
7212 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7213 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7214 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7215 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7216 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7217 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7218 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7219 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7220 { } /* end */
7221};
7222
7223/*
7224 * 8ch mode
7225 */
7226static struct hda_verb alc883_4ST_ch8_init[] = {
7227 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7228 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7229 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7230 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7231 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7232 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7233 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7234 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7235 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7236 { } /* end */
7237};
7238
7239static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7240 { 2, alc883_4ST_ch2_init },
7241 { 4, alc883_4ST_ch4_init },
7242 { 6, alc883_4ST_ch6_init },
7243 { 8, alc883_4ST_ch8_init },
7244};
7245
7246
7247/*
7248 * 2ch mode
7249 */
7250static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7251 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7252 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7253 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7254 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7255 { } /* end */
7256};
7257
7258/*
7259 * 4ch mode
7260 */
7261static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7262 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7263 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7264 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7265 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7266 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7267 { } /* end */
7268};
7269
7270/*
7271 * 6ch mode
7272 */
7273static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7274 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7275 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7276 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7277 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7278 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7279 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7280 { } /* end */
7281};
7282
7283static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7284 { 2, alc883_3ST_ch2_intel_init },
7285 { 4, alc883_3ST_ch4_intel_init },
7286 { 6, alc883_3ST_ch6_intel_init },
7287};
7288
dd7714c9
WF
7289/*
7290 * 2ch mode
7291 */
7292static struct hda_verb alc889_ch2_intel_init[] = {
7293 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7294 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7295 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7296 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7297 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7298 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7299 { } /* end */
7300};
7301
87a8c370
JK
7302/*
7303 * 6ch mode
7304 */
7305static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7306 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7307 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7308 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7309 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7310 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7311 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7312 { } /* end */
7313};
7314
7315/*
7316 * 8ch mode
7317 */
7318static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7319 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7320 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7321 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7322 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7323 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7324 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7325 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7326 { } /* end */
7327};
7328
dd7714c9
WF
7329static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7330 { 2, alc889_ch2_intel_init },
87a8c370
JK
7331 { 6, alc889_ch6_intel_init },
7332 { 8, alc889_ch8_intel_init },
7333};
7334
4953550a
TI
7335/*
7336 * 6ch mode
7337 */
7338static struct hda_verb alc883_sixstack_ch6_init[] = {
7339 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7343 { } /* end */
7344};
7345
7346/*
7347 * 8ch mode
7348 */
7349static struct hda_verb alc883_sixstack_ch8_init[] = {
7350 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7351 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7352 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7353 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7354 { } /* end */
7355};
7356
7357static struct hda_channel_mode alc883_sixstack_modes[2] = {
7358 { 6, alc883_sixstack_ch6_init },
7359 { 8, alc883_sixstack_ch8_init },
7360};
7361
7362
1da177e4
LT
7363/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7364 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7365 */
c8b6bf9b 7366static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7367 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7368 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7369 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7370 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7371 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7372 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7373 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7374 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7375 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7376 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7377 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7388 { } /* end */
7389};
7390
76e6f5a9
RH
7391/* Macbook Air 2,1 same control for HP and internal Speaker */
7392
7393static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7395 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7396 { }
7397};
7398
7399
87350ad0 7400static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7401 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7402 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7403 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7404 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7406 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7407 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7408 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7409 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7410 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7411 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7412 { } /* end */
7413};
41d5545d
KS
7414
7415static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7417 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7418 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7419 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7420 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7421 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7422 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7423 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
41d5545d
KS
7424 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7425 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7427 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7428 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7429 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7430 { } /* end */
7431};
92b9de83 7432
e458b1fa
LY
7433static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7434 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7435 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7436 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7437 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7438 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7439 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7441 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7442 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7443 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7444 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7445 { } /* end */
7446};
7447
4b7e1803
JM
7448static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7449 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7450 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
7451 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7452 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7453 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7454 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7456 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7458 { } /* end */
7459};
7460
7461
bdd148a3
KY
7462static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7463 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7464 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7465 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7466 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7467 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7468 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7469 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7470 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7471 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7472 { } /* end */
7473};
7474
272a527c
KY
7475static struct snd_kcontrol_new alc882_targa_mixer[] = {
7476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7478 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7479 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7480 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7485 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7486 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7487 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7488 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7489 { } /* end */
7490};
7491
7492/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7493 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7494 */
7495static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7496 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7497 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7498 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7499 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7502 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7503 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7504 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7505 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7509 { } /* end */
7510};
7511
914759b7
TI
7512static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7514 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7515 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7516 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7517 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7518 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7519 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7521 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7523 { } /* end */
7524};
7525
df694daa
KY
7526static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7527 {
7528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7529 .name = "Channel Mode",
7530 .info = alc_ch_mode_info,
7531 .get = alc_ch_mode_get,
7532 .put = alc_ch_mode_put,
7533 },
7534 { } /* end */
7535};
7536
4953550a 7537static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7538 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7541 /* Rear mixer */
05acb863
TI
7542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7543 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7544 /* CLFE mixer */
05acb863
TI
7545 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7547 /* Side mixer */
05acb863
TI
7548 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7549 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7550
e9edcee0 7551 /* Front Pin: output 0 (0x0c) */
05acb863 7552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7554 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7555 /* Rear Pin: output 1 (0x0d) */
05acb863 7556 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7557 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7558 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7559 /* CLFE Pin: output 2 (0x0e) */
05acb863 7560 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7561 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7562 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7563 /* Side Pin: output 3 (0x0f) */
05acb863 7564 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7565 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7566 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7567 /* Mic (rear) pin: input vref at 80% */
16ded525 7568 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7569 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7570 /* Front Mic pin: input vref at 80% */
16ded525 7571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7573 /* Line In pin: input */
05acb863 7574 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7575 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7576 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7577 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7578 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7579 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7580 /* CD pin widget for input */
05acb863 7581 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7582
7583 /* FIXME: use matrix-type input source selection */
7584 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7585 /* Input mixer2 */
05acb863 7586 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7587 /* Input mixer3 */
05acb863 7588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7589 /* ADC2: mute amp left and right */
7590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7591 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7592 /* ADC3: mute amp left and right */
7593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7594 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7595
7596 { }
7597};
7598
4953550a
TI
7599static struct hda_verb alc882_adc1_init_verbs[] = {
7600 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7604 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7605 /* ADC1: mute amp left and right */
7606 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7607 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7608 { }
7609};
7610
4b146cb0
TI
7611static struct hda_verb alc882_eapd_verbs[] = {
7612 /* change to EAPD mode */
7613 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7614 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7615 { }
4b146cb0
TI
7616};
7617
87a8c370
JK
7618static struct hda_verb alc889_eapd_verbs[] = {
7619 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7620 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7621 { }
7622};
7623
6732bd0d
WF
7624static struct hda_verb alc_hp15_unsol_verbs[] = {
7625 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7627 {}
7628};
87a8c370
JK
7629
7630static struct hda_verb alc885_init_verbs[] = {
7631 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7632 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7634 /* Rear mixer */
88102f3f
KY
7635 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7637 /* CLFE mixer */
88102f3f
KY
7638 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7639 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7640 /* Side mixer */
88102f3f
KY
7641 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7643
7644 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7646 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7647 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7648 /* Front Pin: output 0 (0x0c) */
7649 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7651 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7652 /* Rear Pin: output 1 (0x0d) */
7653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7655 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7656 /* CLFE Pin: output 2 (0x0e) */
7657 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7658 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7659 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7660 /* Side Pin: output 3 (0x0f) */
7661 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7662 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7663 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7664 /* Mic (rear) pin: input vref at 80% */
7665 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7666 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7667 /* Front Mic pin: input vref at 80% */
7668 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7670 /* Line In pin: input */
7671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7672 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7673
7674 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7675 /* Input mixer1 */
88102f3f 7676 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7677 /* Input mixer2 */
7678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7679 /* Input mixer3 */
88102f3f 7680 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7681 /* ADC2: mute amp left and right */
7682 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 /* ADC3: mute amp left and right */
7684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7685
7686 { }
7687};
7688
7689static struct hda_verb alc885_init_input_verbs[] = {
7690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7693 { }
7694};
7695
7696
7697/* Unmute Selector 24h and set the default input to front mic */
7698static struct hda_verb alc889_init_input_verbs[] = {
7699 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7700 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7701 { }
7702};
7703
7704
4953550a
TI
7705#define alc883_init_verbs alc882_base_init_verbs
7706
9102cd1c
TD
7707/* Mac Pro test */
7708static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7710 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7711 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7714 /* FIXME: this looks suspicious...
d355c82a
JK
7715 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7716 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7717 */
9102cd1c
TD
7718 { } /* end */
7719};
7720
7721static struct hda_verb alc882_macpro_init_verbs[] = {
7722 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7726 /* Front Pin: output 0 (0x0c) */
7727 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7728 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7729 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7730 /* Front Mic pin: input vref at 80% */
7731 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7732 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7733 /* Speaker: output */
7734 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7735 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7736 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7737 /* Headphone output (output 0 - 0x0c) */
7738 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7740 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7741
7742 /* FIXME: use matrix-type input source selection */
7743 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7744 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7747 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7749 /* Input mixer2 */
7750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7754 /* Input mixer3 */
7755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7759 /* ADC1: mute amp left and right */
7760 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7761 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7762 /* ADC2: mute amp left and right */
7763 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7764 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7765 /* ADC3: mute amp left and right */
7766 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7767 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7768
7769 { }
7770};
f12ab1e0 7771
41d5545d
KS
7772/* Macbook 5,1 */
7773static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7774 /* DACs */
7775 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7776 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7777 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7778 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7779 /* Front mixer */
41d5545d
KS
7780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7783 /* Surround mixer */
7784 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7785 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7787 /* LFE mixer */
7788 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7789 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7791 /* HP mixer */
7792 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7795 /* Front Pin (0x0c) */
41d5545d
KS
7796 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7797 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
7798 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7799 /* LFE Pin (0x0e) */
7800 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7801 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7802 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7803 /* HP Pin (0x0f) */
41d5545d
KS
7804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 7806 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 7807 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
7808 /* Front Mic pin: input vref at 80% */
7809 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7810 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7811 /* Line In pin */
7812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7814
7815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7818 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7819 { }
7820};
7821
e458b1fa
LY
7822/* Macmini 3,1 */
7823static struct hda_verb alc885_macmini3_init_verbs[] = {
7824 /* DACs */
7825 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7826 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7827 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7828 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7829 /* Front mixer */
7830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7833 /* Surround mixer */
7834 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7835 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7836 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7837 /* LFE mixer */
7838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7841 /* HP mixer */
7842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7843 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7844 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7845 /* Front Pin (0x0c) */
7846 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7847 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7848 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7849 /* LFE Pin (0x0e) */
7850 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7852 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7853 /* HP Pin (0x0f) */
7854 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7855 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7856 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7857 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7858 /* Line In pin */
7859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7861
7862 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7865 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7866 { }
7867};
7868
76e6f5a9
RH
7869
7870static struct hda_verb alc885_mba21_init_verbs[] = {
7871 /*Internal and HP Speaker Mixer*/
7872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7873 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7875 /*Internal Speaker Pin (0x0c)*/
7876 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7877 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7878 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7879 /* HP Pin: output 0 (0x0e) */
7880 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7881 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7882 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7884 /* Line in (is hp when jack connected)*/
7885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7886 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7887
7888 { }
7889 };
7890
7891
87350ad0
TI
7892/* Macbook Pro rev3 */
7893static struct hda_verb alc885_mbp3_init_verbs[] = {
7894 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7895 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7896 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7897 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7898 /* Rear mixer */
7899 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7900 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7901 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
7902 /* HP mixer */
7903 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7905 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
7906 /* Front Pin: output 0 (0x0c) */
7907 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7909 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 7910 /* HP Pin: output 0 (0x0e) */
87350ad0 7911 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
7912 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7913 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
7914 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7915 /* Mic (rear) pin: input vref at 80% */
7916 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7917 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7918 /* Front Mic pin: input vref at 80% */
7919 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7920 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7921 /* Line In pin: use output 1 when in LineOut mode */
7922 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7923 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7924 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7925
7926 /* FIXME: use matrix-type input source selection */
7927 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7928 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7929 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7930 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7931 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7932 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7933 /* Input mixer2 */
7934 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7935 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7936 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7938 /* Input mixer3 */
7939 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7940 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7941 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7943 /* ADC1: mute amp left and right */
7944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7945 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7946 /* ADC2: mute amp left and right */
7947 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7948 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7949 /* ADC3: mute amp left and right */
7950 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7951 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7952
7953 { }
7954};
7955
4b7e1803
JM
7956/* iMac 9,1 */
7957static struct hda_verb alc885_imac91_init_verbs[] = {
7958 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7962 /* Rear mixer */
7963 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7964 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7966 /* HP Pin: output 0 (0x0c) */
7967 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7969 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7970 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7971 /* Internal Speakers: output 0 (0x0d) */
7972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7974 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7975 /* Mic (rear) pin: input vref at 80% */
7976 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7977 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7978 /* Front Mic pin: input vref at 80% */
7979 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7980 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7981 /* Line In pin: use output 1 when in LineOut mode */
7982 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7983 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7984 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7985
7986 /* FIXME: use matrix-type input source selection */
7987 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7988 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7989 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7990 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7993 /* Input mixer2 */
7994 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7995 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7996 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7997 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7998 /* Input mixer3 */
7999 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8003 /* ADC1: mute amp left and right */
8004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8005 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8006 /* ADC2: mute amp left and right */
8007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8008 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8009 /* ADC3: mute amp left and right */
8010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8011 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8012
8013 { }
8014};
8015
c54728d8
NF
8016/* iMac 24 mixer. */
8017static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8018 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8019 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8020 { } /* end */
8021};
8022
8023/* iMac 24 init verbs. */
8024static struct hda_verb alc885_imac24_init_verbs[] = {
8025 /* Internal speakers: output 0 (0x0c) */
8026 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8027 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8028 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8029 /* Internal speakers: output 0 (0x0c) */
8030 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8031 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8032 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8033 /* Headphone: output 0 (0x0c) */
8034 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8035 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8036 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8037 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8038 /* Front Mic: input vref at 80% */
8039 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8040 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8041 { }
8042};
8043
8044/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8045static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8046{
a9fd4f3f 8047 struct alc_spec *spec = codec->spec;
c54728d8 8048
a9fd4f3f
TI
8049 spec->autocfg.hp_pins[0] = 0x14;
8050 spec->autocfg.speaker_pins[0] = 0x18;
8051 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8052}
8053
9d54f08b
TI
8054#define alc885_mb5_setup alc885_imac24_setup
8055#define alc885_macmini3_setup alc885_imac24_setup
8056
76e6f5a9
RH
8057/* Macbook Air 2,1 */
8058static void alc885_mba21_setup(struct hda_codec *codec)
8059{
8060 struct alc_spec *spec = codec->spec;
8061
8062 spec->autocfg.hp_pins[0] = 0x14;
8063 spec->autocfg.speaker_pins[0] = 0x18;
8064}
8065
8066
8067
4f5d1706 8068static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8069{
a9fd4f3f 8070 struct alc_spec *spec = codec->spec;
87350ad0 8071
a9fd4f3f
TI
8072 spec->autocfg.hp_pins[0] = 0x15;
8073 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8074}
8075
9d54f08b 8076static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8077{
9d54f08b 8078 struct alc_spec *spec = codec->spec;
4b7e1803 8079
9d54f08b
TI
8080 spec->autocfg.hp_pins[0] = 0x14;
8081 spec->autocfg.speaker_pins[0] = 0x15;
8082 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8083}
87350ad0 8084
272a527c
KY
8085static struct hda_verb alc882_targa_verbs[] = {
8086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8087 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8088
8089 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8090 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8091
272a527c
KY
8092 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8093 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8094 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8095
8096 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8097 { } /* end */
8098};
8099
8100/* toggle speaker-output according to the hp-jack state */
8101static void alc882_targa_automute(struct hda_codec *codec)
8102{
a9fd4f3f
TI
8103 struct alc_spec *spec = codec->spec;
8104 alc_automute_amp(codec);
82beb8fd 8105 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8106 spec->jack_present ? 1 : 3);
8107}
8108
4f5d1706 8109static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8110{
8111 struct alc_spec *spec = codec->spec;
8112
8113 spec->autocfg.hp_pins[0] = 0x14;
8114 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8115}
8116
8117static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8118{
a9fd4f3f 8119 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8120 alc882_targa_automute(codec);
272a527c
KY
8121}
8122
8123static struct hda_verb alc882_asus_a7j_verbs[] = {
8124 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8126
8127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8128 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8129 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8130
272a527c
KY
8131 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8132 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8133 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8134
8135 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8136 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8137 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8138 { } /* end */
8139};
8140
914759b7
TI
8141static struct hda_verb alc882_asus_a7m_verbs[] = {
8142 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8143 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8144
8145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8146 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8148
914759b7
TI
8149 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8150 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8151 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8152
8153 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8154 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8155 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8156 { } /* end */
8157};
8158
9102cd1c
TD
8159static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8160{
8161 unsigned int gpiostate, gpiomask, gpiodir;
8162
8163 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8164 AC_VERB_GET_GPIO_DATA, 0);
8165
8166 if (!muted)
8167 gpiostate |= (1 << pin);
8168 else
8169 gpiostate &= ~(1 << pin);
8170
8171 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8172 AC_VERB_GET_GPIO_MASK, 0);
8173 gpiomask |= (1 << pin);
8174
8175 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8176 AC_VERB_GET_GPIO_DIRECTION, 0);
8177 gpiodir |= (1 << pin);
8178
8179
8180 snd_hda_codec_write(codec, codec->afg, 0,
8181 AC_VERB_SET_GPIO_MASK, gpiomask);
8182 snd_hda_codec_write(codec, codec->afg, 0,
8183 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8184
8185 msleep(1);
8186
8187 snd_hda_codec_write(codec, codec->afg, 0,
8188 AC_VERB_SET_GPIO_DATA, gpiostate);
8189}
8190
7debbe51
TI
8191/* set up GPIO at initialization */
8192static void alc885_macpro_init_hook(struct hda_codec *codec)
8193{
8194 alc882_gpio_mute(codec, 0, 0);
8195 alc882_gpio_mute(codec, 1, 0);
8196}
8197
8198/* set up GPIO and update auto-muting at initialization */
8199static void alc885_imac24_init_hook(struct hda_codec *codec)
8200{
8201 alc885_macpro_init_hook(codec);
4f5d1706 8202 alc_automute_amp(codec);
7debbe51
TI
8203}
8204
df694daa
KY
8205/*
8206 * generic initialization of ADC, input mixers and output mixers
8207 */
4953550a 8208static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8209 /*
8210 * Unmute ADC0-2 and set the default input to mic-in
8211 */
4953550a
TI
8212 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8214 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8216
4953550a
TI
8217 /*
8218 * Set up output mixers (0x0c - 0x0f)
8219 */
8220 /* set vol=0 to output mixers */
8221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8223 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8225 /* set up input amps for analog loopback */
8226 /* Amp Indices: DAC = 0, mixer = 1 */
8227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8230 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8231 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8235 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8236 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8237
4953550a
TI
8238 /* FIXME: use matrix-type input source selection */
8239 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8240 /* Input mixer2 */
88102f3f 8241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8242 /* Input mixer3 */
88102f3f 8243 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8244 { }
9c7f852e
TI
8245};
8246
eb4c41d3
TS
8247/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8248static struct hda_verb alc889A_mb31_ch2_init[] = {
8249 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8250 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8251 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8252 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8253 { } /* end */
8254};
8255
8256/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8257static struct hda_verb alc889A_mb31_ch4_init[] = {
8258 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8260 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8261 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8262 { } /* end */
8263};
8264
8265/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8266static struct hda_verb alc889A_mb31_ch5_init[] = {
8267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8268 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8271 { } /* end */
8272};
8273
8274/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8275static struct hda_verb alc889A_mb31_ch6_init[] = {
8276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8277 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8279 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8280 { } /* end */
8281};
8282
8283static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8284 { 2, alc889A_mb31_ch2_init },
8285 { 4, alc889A_mb31_ch4_init },
8286 { 5, alc889A_mb31_ch5_init },
8287 { 6, alc889A_mb31_ch6_init },
8288};
8289
b373bdeb
AN
8290static struct hda_verb alc883_medion_eapd_verbs[] = {
8291 /* eanable EAPD on medion laptop */
8292 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8293 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8294 { }
8295};
8296
4953550a 8297#define alc883_base_mixer alc882_base_mixer
834be88d 8298
a8848bd6
AS
8299static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8300 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8301 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8302 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8303 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8304 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8305 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8307 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8308 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8309 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8310 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8311 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8312 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8313 { } /* end */
8314};
8315
0c4cc443 8316static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8318 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8319 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8320 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8324 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8325 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8326 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8327 { } /* end */
8328};
8329
fb97dc67
J
8330static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8332 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8334 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8336 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, 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),
fb97dc67
J
8341 { } /* end */
8342};
8343
9c7f852e
TI
8344static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8347 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8348 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8349 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8350 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8351 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8352 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8353 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8355 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8356 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8357 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8358 { } /* end */
8359};
df694daa 8360
9c7f852e
TI
8361static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8362 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8364 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8365 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8366 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8367 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8368 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8369 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8370 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8371 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8372 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8373 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8374 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8376 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8378 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8379 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8380 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8381 { } /* end */
8382};
8383
17bba1b7
J
8384static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8385 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8386 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8387 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8388 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8389 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8390 HDA_OUTPUT),
8391 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8392 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8393 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8394 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8395 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8396 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8397 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8398 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8399 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8400 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8401 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8402 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8403 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8404 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8405 { } /* end */
8406};
8407
87a8c370
JK
8408static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8412 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8414 HDA_OUTPUT),
8415 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8416 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8417 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8418 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8419 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8424 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8426 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8427 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8429 { } /* end */
8430};
8431
d1d985f0 8432static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8433 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8434 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8435 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8436 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8437 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8438 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8439 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8440 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8441 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8444 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8445 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8447 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8450 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8451 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8452 { } /* end */
8453};
8454
c259249f 8455static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8456 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8457 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8459 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8460 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8461 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8462 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8463 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8464 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8465 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8466 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8467 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8468 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8469 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8470 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8471 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8473 { } /* end */
f12ab1e0 8474};
ccc656ce 8475
c259249f 8476static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8478 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8479 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8480 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8481 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8482 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8484 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8486 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8487 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8488 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8489 { } /* end */
f12ab1e0 8490};
ccc656ce 8491
b99dba34
TI
8492static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8493 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8494 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8495 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8496 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8497 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8498 { } /* end */
8499};
8500
bc9f98a9
KY
8501static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8502 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8503 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8504 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8505 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8510 { } /* end */
f12ab1e0 8511};
bc9f98a9 8512
272a527c
KY
8513static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8514 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8515 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8516 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8517 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8518 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8519 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8520 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8521 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8522 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8523 { } /* end */
8524};
8525
8526static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8527 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8528 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8529 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8532 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8534 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8535 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8536 { } /* end */
ea1fb29a 8537};
272a527c 8538
2880a867 8539static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8545 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8546 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8548 { } /* end */
d1a991a6 8549};
2880a867 8550
d2fd4b09
TV
8551static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8552 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8553 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8554 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8555 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
684a8842
TV
8556 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8557 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8558 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8559 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8561 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8562 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8563 { } /* end */
8564};
8565
e2757d5e
KY
8566static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8567 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8568 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8569 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8570 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8571 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8572 0x0d, 1, 0x0, HDA_OUTPUT),
8573 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8574 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8575 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8576 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8577 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8580 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8581 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8583 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8585 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8586 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8588 { } /* end */
8589};
8590
eb4c41d3
TS
8591static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8592 /* Output mixers */
8593 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8594 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8595 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8596 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8597 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8598 HDA_OUTPUT),
8599 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8600 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8601 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8602 /* Output switches */
8603 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8604 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8605 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8606 /* Boost mixers */
8607 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8608 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8609 /* Input mixers */
8610 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8611 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8612 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8613 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8614 { } /* end */
8615};
8616
3e1647c5
GG
8617static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8618 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8619 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8622 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8623 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8624 { } /* end */
8625};
8626
e2757d5e
KY
8627static struct hda_bind_ctls alc883_bind_cap_vol = {
8628 .ops = &snd_hda_bind_vol,
8629 .values = {
8630 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8631 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8632 0
8633 },
8634};
8635
8636static struct hda_bind_ctls alc883_bind_cap_switch = {
8637 .ops = &snd_hda_bind_sw,
8638 .values = {
8639 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8640 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8641 0
8642 },
8643};
8644
8645static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8646 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8647 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8652 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8654 { } /* end */
8655};
df694daa 8656
4953550a
TI
8657static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8658 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8659 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8660 {
8661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8662 /* .name = "Capture Source", */
8663 .name = "Input Source",
8664 .count = 1,
8665 .info = alc_mux_enum_info,
8666 .get = alc_mux_enum_get,
8667 .put = alc_mux_enum_put,
8668 },
8669 { } /* end */
8670};
9c7f852e 8671
4953550a
TI
8672static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8673 {
8674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8675 .name = "Channel Mode",
8676 .info = alc_ch_mode_info,
8677 .get = alc_ch_mode_get,
8678 .put = alc_ch_mode_put,
8679 },
8680 { } /* end */
9c7f852e
TI
8681};
8682
a8848bd6 8683/* toggle speaker-output according to the hp-jack state */
4f5d1706 8684static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8685{
a9fd4f3f 8686 struct alc_spec *spec = codec->spec;
a8848bd6 8687
a9fd4f3f
TI
8688 spec->autocfg.hp_pins[0] = 0x15;
8689 spec->autocfg.speaker_pins[0] = 0x14;
8690 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8691}
8692
8693/* auto-toggle front mic */
8694/*
8695static void alc883_mitac_mic_automute(struct hda_codec *codec)
8696{
864f92be 8697 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8698
a8848bd6
AS
8699 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8700}
8701*/
8702
a8848bd6
AS
8703static struct hda_verb alc883_mitac_verbs[] = {
8704 /* HP */
8705 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8707 /* Subwoofer */
8708 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8709 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8710
8711 /* enable unsolicited event */
8712 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8713 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8714
8715 { } /* end */
8716};
8717
a65cc60f 8718static struct hda_verb alc883_clevo_m540r_verbs[] = {
8719 /* HP */
8720 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8721 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8722 /* Int speaker */
8723 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8724
8725 /* enable unsolicited event */
8726 /*
8727 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8728 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8729 */
8730
8731 { } /* end */
8732};
8733
0c4cc443 8734static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8735 /* HP */
8736 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8737 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8738 /* Int speaker */
8739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8741
8742 /* enable unsolicited event */
8743 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8744 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8745
8746 { } /* end */
8747};
8748
fb97dc67
J
8749static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8750 /* HP */
8751 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8753 /* Subwoofer */
8754 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8756
8757 /* enable unsolicited event */
8758 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8759
8760 { } /* end */
8761};
8762
c259249f 8763static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8766
8767 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8769
64a8be74
DH
8770/* Connect Line-Out side jack (SPDIF) to Side */
8771 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8772 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8773 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8774/* Connect Mic jack to CLFE */
8775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8777 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8778/* Connect Line-in jack to Surround */
8779 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8780 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8781 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8782/* Connect HP out jack to Front */
8783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
8786
8787 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
8788
8789 { } /* end */
8790};
8791
bc9f98a9
KY
8792static struct hda_verb alc883_lenovo_101e_verbs[] = {
8793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8794 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8795 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8796 { } /* end */
8797};
8798
272a527c
KY
8799static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8800 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8802 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8803 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8804 { } /* end */
8805};
8806
8807static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8810 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8811 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8812 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8813 { } /* end */
8814};
8815
189609ae
KY
8816static struct hda_verb alc883_haier_w66_verbs[] = {
8817 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8818 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8819
8820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8821
8822 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8824 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8826 { } /* end */
8827};
8828
e2757d5e
KY
8829static struct hda_verb alc888_lenovo_sky_verbs[] = {
8830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8832 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8833 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8834 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8835 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8836 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8837 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8838 { } /* end */
8839};
8840
8718b700
HRK
8841static struct hda_verb alc888_6st_dell_verbs[] = {
8842 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8843 { }
8844};
8845
3e1647c5
GG
8846static struct hda_verb alc883_vaiott_verbs[] = {
8847 /* HP */
8848 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8850
8851 /* enable unsolicited event */
8852 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8853
8854 { } /* end */
8855};
8856
4f5d1706 8857static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 8858{
a9fd4f3f 8859 struct alc_spec *spec = codec->spec;
8718b700 8860
a9fd4f3f
TI
8861 spec->autocfg.hp_pins[0] = 0x1b;
8862 spec->autocfg.speaker_pins[0] = 0x14;
8863 spec->autocfg.speaker_pins[1] = 0x16;
8864 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
8865}
8866
4723c022 8867static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8868 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8869 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8870 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8871 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8872 { } /* end */
5795b9e6
CM
8873};
8874
3ea0d7cf
HRK
8875/*
8876 * 2ch mode
8877 */
4723c022 8878static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8879 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8880 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8881 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8882 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8883 { } /* end */
8341de60
CM
8884};
8885
3ea0d7cf
HRK
8886/*
8887 * 4ch mode
8888 */
8889static struct hda_verb alc888_3st_hp_4ch_init[] = {
8890 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8891 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8892 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8893 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8894 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8895 { } /* end */
8896};
8897
8898/*
8899 * 6ch mode
8900 */
4723c022 8901static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8902 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8903 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8904 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8905 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8906 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8907 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8908 { } /* end */
8341de60
CM
8909};
8910
3ea0d7cf 8911static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8912 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8913 { 4, alc888_3st_hp_4ch_init },
4723c022 8914 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8915};
8916
272a527c
KY
8917/* toggle front-jack and RCA according to the hp-jack state */
8918static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8919{
864f92be 8920 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 8921
47fd830a
TI
8922 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8923 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8924 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8925 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8926}
8927
8928/* toggle RCA according to the front-jack state */
8929static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8930{
864f92be 8931 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 8932
47fd830a
TI
8933 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8934 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8935}
47fd830a 8936
272a527c
KY
8937static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8938 unsigned int res)
8939{
8940 if ((res >> 26) == ALC880_HP_EVENT)
8941 alc888_lenovo_ms7195_front_automute(codec);
8942 if ((res >> 26) == ALC880_FRONT_EVENT)
8943 alc888_lenovo_ms7195_rca_automute(codec);
8944}
8945
8946static struct hda_verb alc883_medion_md2_verbs[] = {
8947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8949
8950 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8951
8952 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8953 { } /* end */
8954};
8955
8956/* toggle speaker-output according to the hp-jack state */
4f5d1706 8957static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 8958{
a9fd4f3f 8959 struct alc_spec *spec = codec->spec;
272a527c 8960
a9fd4f3f
TI
8961 spec->autocfg.hp_pins[0] = 0x14;
8962 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
8963}
8964
ccc656ce 8965/* toggle speaker-output according to the hp-jack state */
c259249f
SA
8966#define alc883_targa_init_hook alc882_targa_init_hook
8967#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 8968
0c4cc443
HRK
8969static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8970{
8971 unsigned int present;
8972
d56757ab 8973 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
8974 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8975 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8976}
8977
4f5d1706 8978static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 8979{
a9fd4f3f
TI
8980 struct alc_spec *spec = codec->spec;
8981
8982 spec->autocfg.hp_pins[0] = 0x15;
8983 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
8984}
8985
8986static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8987{
a9fd4f3f 8988 alc_automute_amp(codec);
0c4cc443
HRK
8989 alc883_clevo_m720_mic_automute(codec);
8990}
8991
8992static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8993 unsigned int res)
8994{
0c4cc443 8995 switch (res >> 26) {
0c4cc443
HRK
8996 case ALC880_MIC_EVENT:
8997 alc883_clevo_m720_mic_automute(codec);
8998 break;
a9fd4f3f
TI
8999 default:
9000 alc_automute_amp_unsol_event(codec, res);
9001 break;
0c4cc443 9002 }
368c7a95
J
9003}
9004
fb97dc67 9005/* toggle speaker-output according to the hp-jack state */
4f5d1706 9006static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9007{
a9fd4f3f 9008 struct alc_spec *spec = codec->spec;
fb97dc67 9009
a9fd4f3f
TI
9010 spec->autocfg.hp_pins[0] = 0x14;
9011 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9012}
9013
4f5d1706 9014static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9015{
a9fd4f3f 9016 struct alc_spec *spec = codec->spec;
189609ae 9017
a9fd4f3f
TI
9018 spec->autocfg.hp_pins[0] = 0x1b;
9019 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9020}
9021
bc9f98a9
KY
9022static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9023{
864f92be 9024 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9025
47fd830a
TI
9026 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9027 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9028}
9029
9030static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9031{
864f92be 9032 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9033
47fd830a
TI
9034 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9035 HDA_AMP_MUTE, bits);
9036 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9037 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9038}
9039
9040static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9041 unsigned int res)
9042{
9043 if ((res >> 26) == ALC880_HP_EVENT)
9044 alc883_lenovo_101e_all_automute(codec);
9045 if ((res >> 26) == ALC880_FRONT_EVENT)
9046 alc883_lenovo_101e_ispeaker_automute(codec);
9047}
9048
676a9b53 9049/* toggle speaker-output according to the hp-jack state */
4f5d1706 9050static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9051{
a9fd4f3f 9052 struct alc_spec *spec = codec->spec;
676a9b53 9053
a9fd4f3f
TI
9054 spec->autocfg.hp_pins[0] = 0x14;
9055 spec->autocfg.speaker_pins[0] = 0x15;
9056 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9057}
9058
d1a991a6
KY
9059static struct hda_verb alc883_acer_eapd_verbs[] = {
9060 /* HP Pin: output 0 (0x0c) */
9061 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9062 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9063 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9064 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9065 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9066 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9067 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9068 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9069 /* eanable EAPD on medion laptop */
9070 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9071 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9072 /* enable unsolicited event */
9073 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9074 { }
9075};
9076
fc86f954
DK
9077static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9078 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9079 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9081 { } /* end */
9082};
9083
4f5d1706 9084static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9085{
a9fd4f3f 9086 struct alc_spec *spec = codec->spec;
5795b9e6 9087
a9fd4f3f
TI
9088 spec->autocfg.hp_pins[0] = 0x1b;
9089 spec->autocfg.speaker_pins[0] = 0x14;
9090 spec->autocfg.speaker_pins[1] = 0x15;
9091 spec->autocfg.speaker_pins[2] = 0x16;
9092 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9093}
9094
4f5d1706 9095static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9096{
a9fd4f3f 9097 struct alc_spec *spec = codec->spec;
e2757d5e 9098
a9fd4f3f
TI
9099 spec->autocfg.hp_pins[0] = 0x1b;
9100 spec->autocfg.speaker_pins[0] = 0x14;
9101 spec->autocfg.speaker_pins[1] = 0x15;
9102 spec->autocfg.speaker_pins[2] = 0x16;
9103 spec->autocfg.speaker_pins[3] = 0x17;
9104 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9105}
9106
4f5d1706 9107static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9108{
9109 struct alc_spec *spec = codec->spec;
9110
9111 spec->autocfg.hp_pins[0] = 0x15;
9112 spec->autocfg.speaker_pins[0] = 0x14;
9113 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9114}
9115
e2757d5e
KY
9116static struct hda_verb alc888_asus_m90v_verbs[] = {
9117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9120 /* enable unsolicited event */
9121 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9122 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9123 { } /* end */
9124};
9125
4f5d1706 9126static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9127{
a9fd4f3f 9128 struct alc_spec *spec = codec->spec;
e2757d5e 9129
a9fd4f3f
TI
9130 spec->autocfg.hp_pins[0] = 0x1b;
9131 spec->autocfg.speaker_pins[0] = 0x14;
9132 spec->autocfg.speaker_pins[1] = 0x15;
9133 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9134 spec->ext_mic.pin = 0x18;
9135 spec->int_mic.pin = 0x19;
9136 spec->ext_mic.mux_idx = 0;
9137 spec->int_mic.mux_idx = 1;
9138 spec->auto_mic = 1;
e2757d5e
KY
9139}
9140
9141static struct hda_verb alc888_asus_eee1601_verbs[] = {
9142 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9143 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9146 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9147 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9148 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9149 /* enable unsolicited event */
9150 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9151 { } /* end */
9152};
9153
e2757d5e
KY
9154static void alc883_eee1601_inithook(struct hda_codec *codec)
9155{
a9fd4f3f
TI
9156 struct alc_spec *spec = codec->spec;
9157
9158 spec->autocfg.hp_pins[0] = 0x14;
9159 spec->autocfg.speaker_pins[0] = 0x1b;
9160 alc_automute_pin(codec);
e2757d5e
KY
9161}
9162
eb4c41d3
TS
9163static struct hda_verb alc889A_mb31_verbs[] = {
9164 /* Init rear pin (used as headphone output) */
9165 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9167 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9168 /* Init line pin (used as output in 4ch and 6ch mode) */
9169 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9170 /* Init line 2 pin (used as headphone out by default) */
9171 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9172 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9173 { } /* end */
9174};
9175
9176/* Mute speakers according to the headphone jack state */
9177static void alc889A_mb31_automute(struct hda_codec *codec)
9178{
9179 unsigned int present;
9180
9181 /* Mute only in 2ch or 4ch mode */
9182 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9183 == 0x00) {
864f92be 9184 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9185 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9186 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9187 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9188 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9189 }
9190}
9191
9192static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9193{
9194 if ((res >> 26) == ALC880_HP_EVENT)
9195 alc889A_mb31_automute(codec);
9196}
9197
4953550a 9198
cb53c626 9199#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9200#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9201#endif
9202
def319f9 9203/* pcm configuration: identical with ALC880 */
4953550a
TI
9204#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9205#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9206#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9207#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9208
9209static hda_nid_t alc883_slave_dig_outs[] = {
9210 ALC1200_DIGOUT_NID, 0,
9211};
9212
9213static hda_nid_t alc1200_slave_dig_outs[] = {
9214 ALC883_DIGOUT_NID, 0,
9215};
9c7f852e
TI
9216
9217/*
9218 * configuration and preset
9219 */
4953550a
TI
9220static const char *alc882_models[ALC882_MODEL_LAST] = {
9221 [ALC882_3ST_DIG] = "3stack-dig",
9222 [ALC882_6ST_DIG] = "6stack-dig",
9223 [ALC882_ARIMA] = "arima",
9224 [ALC882_W2JC] = "w2jc",
9225 [ALC882_TARGA] = "targa",
9226 [ALC882_ASUS_A7J] = "asus-a7j",
9227 [ALC882_ASUS_A7M] = "asus-a7m",
9228 [ALC885_MACPRO] = "macpro",
9229 [ALC885_MB5] = "mb5",
e458b1fa 9230 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9231 [ALC885_MBA21] = "mba21",
4953550a
TI
9232 [ALC885_MBP3] = "mbp3",
9233 [ALC885_IMAC24] = "imac24",
4b7e1803 9234 [ALC885_IMAC91] = "imac91",
4953550a 9235 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9236 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9237 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9238 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9239 [ALC883_TARGA_DIG] = "targa-dig",
9240 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9241 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9242 [ALC883_ACER] = "acer",
2880a867 9243 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9244 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9245 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9246 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9247 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9248 [ALC883_MEDION] = "medion",
272a527c 9249 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 9250 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9251 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9252 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9253 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9254 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9255 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9256 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9257 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9258 [ALC883_MITAC] = "mitac",
a65cc60f 9259 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9260 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9261 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9262 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9263 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9264 [ALC889A_INTEL] = "intel-alc889a",
9265 [ALC889_INTEL] = "intel-x58",
3ab90935 9266 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9267 [ALC889A_MB31] = "mb31",
3e1647c5 9268 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9269 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9270};
9271
4953550a
TI
9272static struct snd_pci_quirk alc882_cfg_tbl[] = {
9273 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9274
ac3e3741 9275 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9276 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9277 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9278 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9279 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9280 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9281 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9282 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9283 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9284 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9285 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9286 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9287 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9288 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9289 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9290 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9291 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9292 ALC888_ACER_ASPIRE_6530G),
cc374c47 9293 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9294 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9295 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9296 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9297 /* default Acer -- disabled as it causes more problems.
9298 * model=auto should work fine now
9299 */
9300 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9301
5795b9e6 9302 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9303
febe3375 9304 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9305 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9306 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9307 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9308 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9309 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9310
9311 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9312 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9313 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9314 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9315 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9316 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9317 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9318 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9319 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9320 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9321 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9322
9323 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9324 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9325 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9326 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9327 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9328 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9329 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9330 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9331 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9332
6f3bf657 9333 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9334 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9335 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9336 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9337 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9338 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9339 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9340 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9341 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9342 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9343 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9344 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9345 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9346 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9347 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9348 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9349 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9350 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9351 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9352 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9353 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9354 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9355 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9356 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9357 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9358 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9359 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9360 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9361 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9362 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9363 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9364
ac3e3741 9365 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
9366 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9367 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9368 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9369 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9370 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9371 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9372 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9373 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9374 ALC883_FUJITSU_PI2515),
bfb53037 9375 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9376 ALC888_FUJITSU_XA3530),
272a527c 9377 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9378 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9379 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9380 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9381 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9382 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9383 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9384 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9385 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9386
17bba1b7
J
9387 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9388 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9389 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9390 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9391 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9392 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9393 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9394
4953550a 9395 {}
f3cd3f5d
WF
9396};
9397
4953550a
TI
9398/* codec SSID table for Intel Mac */
9399static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9400 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9401 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9402 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9403 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9404 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9405 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9406 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9407 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9408 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9409 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9410 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9411 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
46ef6ec9
DC
9412 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9413 * so apparently no perfect solution yet
4953550a
TI
9414 */
9415 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9416 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9417 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9418 {} /* terminator */
b25c9da1
WF
9419};
9420
4953550a
TI
9421static struct alc_config_preset alc882_presets[] = {
9422 [ALC882_3ST_DIG] = {
9423 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9424 .init_verbs = { alc882_base_init_verbs,
9425 alc882_adc1_init_verbs },
4953550a
TI
9426 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9427 .dac_nids = alc882_dac_nids,
9428 .dig_out_nid = ALC882_DIGOUT_NID,
9429 .dig_in_nid = ALC882_DIGIN_NID,
9430 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9431 .channel_mode = alc882_ch_modes,
9432 .need_dac_fix = 1,
9433 .input_mux = &alc882_capture_source,
9434 },
9435 [ALC882_6ST_DIG] = {
9436 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9437 .init_verbs = { alc882_base_init_verbs,
9438 alc882_adc1_init_verbs },
4953550a
TI
9439 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9440 .dac_nids = alc882_dac_nids,
9441 .dig_out_nid = ALC882_DIGOUT_NID,
9442 .dig_in_nid = ALC882_DIGIN_NID,
9443 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9444 .channel_mode = alc882_sixstack_modes,
9445 .input_mux = &alc882_capture_source,
9446 },
9447 [ALC882_ARIMA] = {
9448 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9449 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9450 alc882_eapd_verbs },
4953550a
TI
9451 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9452 .dac_nids = alc882_dac_nids,
9453 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9454 .channel_mode = alc882_sixstack_modes,
9455 .input_mux = &alc882_capture_source,
9456 },
9457 [ALC882_W2JC] = {
9458 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9459 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9460 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9461 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9462 .dac_nids = alc882_dac_nids,
9463 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9464 .channel_mode = alc880_threestack_modes,
9465 .need_dac_fix = 1,
9466 .input_mux = &alc882_capture_source,
9467 .dig_out_nid = ALC882_DIGOUT_NID,
9468 },
76e6f5a9
RH
9469 [ALC885_MBA21] = {
9470 .mixers = { alc885_mba21_mixer },
9471 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9472 .num_dacs = 2,
9473 .dac_nids = alc882_dac_nids,
9474 .channel_mode = alc885_mba21_ch_modes,
9475 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9476 .input_mux = &alc882_capture_source,
9477 .unsol_event = alc_automute_amp_unsol_event,
9478 .setup = alc885_mba21_setup,
9479 .init_hook = alc_automute_amp,
9480 },
4953550a
TI
9481 [ALC885_MBP3] = {
9482 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9483 .init_verbs = { alc885_mbp3_init_verbs,
9484 alc880_gpio1_init_verbs },
be0ae923 9485 .num_dacs = 2,
4953550a 9486 .dac_nids = alc882_dac_nids,
be0ae923
TI
9487 .hp_nid = 0x04,
9488 .channel_mode = alc885_mbp_4ch_modes,
9489 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9490 .input_mux = &alc882_capture_source,
9491 .dig_out_nid = ALC882_DIGOUT_NID,
9492 .dig_in_nid = ALC882_DIGIN_NID,
9493 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9494 .setup = alc885_mbp3_setup,
9495 .init_hook = alc_automute_amp,
4953550a
TI
9496 },
9497 [ALC885_MB5] = {
9498 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9499 .init_verbs = { alc885_mb5_init_verbs,
9500 alc880_gpio1_init_verbs },
9501 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9502 .dac_nids = alc882_dac_nids,
9503 .channel_mode = alc885_mb5_6ch_modes,
9504 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9505 .input_mux = &mb5_capture_source,
9506 .dig_out_nid = ALC882_DIGOUT_NID,
9507 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9508 .unsol_event = alc_automute_amp_unsol_event,
9509 .setup = alc885_mb5_setup,
9510 .init_hook = alc_automute_amp,
4953550a 9511 },
e458b1fa
LY
9512 [ALC885_MACMINI3] = {
9513 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9514 .init_verbs = { alc885_macmini3_init_verbs,
9515 alc880_gpio1_init_verbs },
9516 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9517 .dac_nids = alc882_dac_nids,
9518 .channel_mode = alc885_macmini3_6ch_modes,
9519 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9520 .input_mux = &macmini3_capture_source,
9521 .dig_out_nid = ALC882_DIGOUT_NID,
9522 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9523 .unsol_event = alc_automute_amp_unsol_event,
9524 .setup = alc885_macmini3_setup,
9525 .init_hook = alc_automute_amp,
e458b1fa 9526 },
4953550a
TI
9527 [ALC885_MACPRO] = {
9528 .mixers = { alc882_macpro_mixer },
9529 .init_verbs = { alc882_macpro_init_verbs },
9530 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9531 .dac_nids = alc882_dac_nids,
9532 .dig_out_nid = ALC882_DIGOUT_NID,
9533 .dig_in_nid = ALC882_DIGIN_NID,
9534 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9535 .channel_mode = alc882_ch_modes,
9536 .input_mux = &alc882_capture_source,
9537 .init_hook = alc885_macpro_init_hook,
9538 },
9539 [ALC885_IMAC24] = {
9540 .mixers = { alc885_imac24_mixer },
9541 .init_verbs = { alc885_imac24_init_verbs },
9542 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9543 .dac_nids = alc882_dac_nids,
9544 .dig_out_nid = ALC882_DIGOUT_NID,
9545 .dig_in_nid = ALC882_DIGIN_NID,
9546 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9547 .channel_mode = alc882_ch_modes,
9548 .input_mux = &alc882_capture_source,
9549 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9550 .setup = alc885_imac24_setup,
4953550a
TI
9551 .init_hook = alc885_imac24_init_hook,
9552 },
4b7e1803
JM
9553 [ALC885_IMAC91] = {
9554 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
9555 .init_verbs = { alc885_imac91_init_verbs,
9556 alc880_gpio1_init_verbs },
9557 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9558 .dac_nids = alc882_dac_nids,
9559 .channel_mode = alc885_mbp_4ch_modes,
9560 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9561 .input_mux = &alc882_capture_source,
9562 .dig_out_nid = ALC882_DIGOUT_NID,
9563 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9564 .unsol_event = alc_automute_amp_unsol_event,
9565 .setup = alc885_imac91_setup,
9566 .init_hook = alc_automute_amp,
4b7e1803 9567 },
4953550a
TI
9568 [ALC882_TARGA] = {
9569 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9570 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9571 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9572 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9573 .dac_nids = alc882_dac_nids,
9574 .dig_out_nid = ALC882_DIGOUT_NID,
9575 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9576 .adc_nids = alc882_adc_nids,
9577 .capsrc_nids = alc882_capsrc_nids,
9578 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9579 .channel_mode = alc882_3ST_6ch_modes,
9580 .need_dac_fix = 1,
9581 .input_mux = &alc882_capture_source,
9582 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9583 .setup = alc882_targa_setup,
9584 .init_hook = alc882_targa_automute,
4953550a
TI
9585 },
9586 [ALC882_ASUS_A7J] = {
9587 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9588 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9589 alc882_asus_a7j_verbs},
4953550a
TI
9590 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9591 .dac_nids = alc882_dac_nids,
9592 .dig_out_nid = ALC882_DIGOUT_NID,
9593 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9594 .adc_nids = alc882_adc_nids,
9595 .capsrc_nids = alc882_capsrc_nids,
9596 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9597 .channel_mode = alc882_3ST_6ch_modes,
9598 .need_dac_fix = 1,
9599 .input_mux = &alc882_capture_source,
9600 },
9601 [ALC882_ASUS_A7M] = {
9602 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9603 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9604 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9605 alc882_asus_a7m_verbs },
9606 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9607 .dac_nids = alc882_dac_nids,
9608 .dig_out_nid = ALC882_DIGOUT_NID,
9609 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9610 .channel_mode = alc880_threestack_modes,
9611 .need_dac_fix = 1,
9612 .input_mux = &alc882_capture_source,
9613 },
9c7f852e
TI
9614 [ALC883_3ST_2ch_DIG] = {
9615 .mixers = { alc883_3ST_2ch_mixer },
9616 .init_verbs = { alc883_init_verbs },
9617 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9618 .dac_nids = alc883_dac_nids,
9619 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9620 .dig_in_nid = ALC883_DIGIN_NID,
9621 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9622 .channel_mode = alc883_3ST_2ch_modes,
9623 .input_mux = &alc883_capture_source,
9624 },
9625 [ALC883_3ST_6ch_DIG] = {
9626 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9627 .init_verbs = { alc883_init_verbs },
9628 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9629 .dac_nids = alc883_dac_nids,
9630 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9631 .dig_in_nid = ALC883_DIGIN_NID,
9632 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9633 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9634 .need_dac_fix = 1,
9c7f852e 9635 .input_mux = &alc883_capture_source,
f12ab1e0 9636 },
9c7f852e
TI
9637 [ALC883_3ST_6ch] = {
9638 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9639 .init_verbs = { alc883_init_verbs },
9640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9641 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9642 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9643 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9644 .need_dac_fix = 1,
9c7f852e 9645 .input_mux = &alc883_capture_source,
f12ab1e0 9646 },
17bba1b7
J
9647 [ALC883_3ST_6ch_INTEL] = {
9648 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9649 .init_verbs = { alc883_init_verbs },
9650 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9651 .dac_nids = alc883_dac_nids,
9652 .dig_out_nid = ALC883_DIGOUT_NID,
9653 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9654 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9655 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9656 .channel_mode = alc883_3ST_6ch_intel_modes,
9657 .need_dac_fix = 1,
9658 .input_mux = &alc883_3stack_6ch_intel,
9659 },
87a8c370
JK
9660 [ALC889A_INTEL] = {
9661 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9662 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9663 alc_hp15_unsol_verbs },
87a8c370
JK
9664 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9665 .dac_nids = alc883_dac_nids,
9666 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9667 .adc_nids = alc889_adc_nids,
9668 .dig_out_nid = ALC883_DIGOUT_NID,
9669 .dig_in_nid = ALC883_DIGIN_NID,
9670 .slave_dig_outs = alc883_slave_dig_outs,
9671 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9672 .channel_mode = alc889_8ch_intel_modes,
9673 .capsrc_nids = alc889_capsrc_nids,
9674 .input_mux = &alc889_capture_source,
4f5d1706
TI
9675 .setup = alc889_automute_setup,
9676 .init_hook = alc_automute_amp,
6732bd0d 9677 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9678 .need_dac_fix = 1,
9679 },
9680 [ALC889_INTEL] = {
9681 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9682 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9683 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9684 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9685 .dac_nids = alc883_dac_nids,
9686 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9687 .adc_nids = alc889_adc_nids,
9688 .dig_out_nid = ALC883_DIGOUT_NID,
9689 .dig_in_nid = ALC883_DIGIN_NID,
9690 .slave_dig_outs = alc883_slave_dig_outs,
9691 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9692 .channel_mode = alc889_8ch_intel_modes,
9693 .capsrc_nids = alc889_capsrc_nids,
9694 .input_mux = &alc889_capture_source,
4f5d1706 9695 .setup = alc889_automute_setup,
6732bd0d
WF
9696 .init_hook = alc889_intel_init_hook,
9697 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9698 .need_dac_fix = 1,
9699 },
9c7f852e
TI
9700 [ALC883_6ST_DIG] = {
9701 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9702 .init_verbs = { alc883_init_verbs },
9703 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9704 .dac_nids = alc883_dac_nids,
9705 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9706 .dig_in_nid = ALC883_DIGIN_NID,
9707 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9708 .channel_mode = alc883_sixstack_modes,
9709 .input_mux = &alc883_capture_source,
9710 },
ccc656ce 9711 [ALC883_TARGA_DIG] = {
c259249f 9712 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9713 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9714 alc883_targa_verbs},
ccc656ce
KY
9715 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9716 .dac_nids = alc883_dac_nids,
9717 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9718 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9719 .channel_mode = alc883_3ST_6ch_modes,
9720 .need_dac_fix = 1,
9721 .input_mux = &alc883_capture_source,
c259249f 9722 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9723 .setup = alc882_targa_setup,
9724 .init_hook = alc882_targa_automute,
ccc656ce
KY
9725 },
9726 [ALC883_TARGA_2ch_DIG] = {
c259249f 9727 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9728 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9729 alc883_targa_verbs},
ccc656ce
KY
9730 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9731 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9732 .adc_nids = alc883_adc_nids_alt,
9733 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9734 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9735 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9736 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9737 .channel_mode = alc883_3ST_2ch_modes,
9738 .input_mux = &alc883_capture_source,
c259249f 9739 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9740 .setup = alc882_targa_setup,
9741 .init_hook = alc882_targa_automute,
ccc656ce 9742 },
64a8be74 9743 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9744 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9745 alc883_chmode_mixer },
64a8be74 9746 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9747 alc883_targa_verbs },
64a8be74
DH
9748 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9749 .dac_nids = alc883_dac_nids,
9750 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9751 .adc_nids = alc883_adc_nids_rev,
9752 .capsrc_nids = alc883_capsrc_nids_rev,
9753 .dig_out_nid = ALC883_DIGOUT_NID,
9754 .dig_in_nid = ALC883_DIGIN_NID,
9755 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9756 .channel_mode = alc883_4ST_8ch_modes,
9757 .need_dac_fix = 1,
9758 .input_mux = &alc883_capture_source,
c259249f 9759 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9760 .setup = alc882_targa_setup,
9761 .init_hook = alc882_targa_automute,
64a8be74 9762 },
bab282b9 9763 [ALC883_ACER] = {
676a9b53 9764 .mixers = { alc883_base_mixer },
bab282b9
VA
9765 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9766 * and the headphone jack. Turn this on and rely on the
9767 * standard mute methods whenever the user wants to turn
9768 * these outputs off.
9769 */
9770 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9771 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9772 .dac_nids = alc883_dac_nids,
bab282b9
VA
9773 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9774 .channel_mode = alc883_3ST_2ch_modes,
9775 .input_mux = &alc883_capture_source,
9776 },
2880a867 9777 [ALC883_ACER_ASPIRE] = {
676a9b53 9778 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 9779 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
9780 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9781 .dac_nids = alc883_dac_nids,
9782 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
9783 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9784 .channel_mode = alc883_3ST_2ch_modes,
9785 .input_mux = &alc883_capture_source,
a9fd4f3f 9786 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9787 .setup = alc883_acer_aspire_setup,
9788 .init_hook = alc_automute_amp,
d1a991a6 9789 },
5b2d1eca 9790 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 9791 .mixers = { alc888_base_mixer,
5b2d1eca
VP
9792 alc883_chmode_mixer },
9793 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9794 alc888_acer_aspire_4930g_verbs },
9795 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9796 .dac_nids = alc883_dac_nids,
9797 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9798 .adc_nids = alc883_adc_nids_rev,
9799 .capsrc_nids = alc883_capsrc_nids_rev,
9800 .dig_out_nid = ALC883_DIGOUT_NID,
9801 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9802 .channel_mode = alc883_3ST_6ch_modes,
9803 .need_dac_fix = 1,
973b8cb0 9804 .const_channel_count = 6,
5b2d1eca 9805 .num_mux_defs =
ef8ef5fb
VP
9806 ARRAY_SIZE(alc888_2_capture_sources),
9807 .input_mux = alc888_2_capture_sources,
d2fd4b09 9808 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9809 .setup = alc888_acer_aspire_4930g_setup,
9810 .init_hook = alc_automute_amp,
d2fd4b09
TV
9811 },
9812 [ALC888_ACER_ASPIRE_6530G] = {
9813 .mixers = { alc888_acer_aspire_6530_mixer },
9814 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9815 alc888_acer_aspire_6530g_verbs },
9816 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9817 .dac_nids = alc883_dac_nids,
9818 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9819 .adc_nids = alc883_adc_nids_rev,
9820 .capsrc_nids = alc883_capsrc_nids_rev,
9821 .dig_out_nid = ALC883_DIGOUT_NID,
9822 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9823 .channel_mode = alc883_3ST_2ch_modes,
9824 .num_mux_defs =
9825 ARRAY_SIZE(alc888_2_capture_sources),
9826 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 9827 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9828 .setup = alc888_acer_aspire_6530g_setup,
9829 .init_hook = alc_automute_amp,
5b2d1eca 9830 },
3b315d70 9831 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 9832 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
9833 alc883_chmode_mixer },
9834 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
9835 alc889_acer_aspire_8930g_verbs,
9836 alc889_eapd_verbs},
3b315d70
HM
9837 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9838 .dac_nids = alc883_dac_nids,
018df418
HM
9839 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9840 .adc_nids = alc889_adc_nids,
9841 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
9842 .dig_out_nid = ALC883_DIGOUT_NID,
9843 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9844 .channel_mode = alc883_3ST_6ch_modes,
9845 .need_dac_fix = 1,
9846 .const_channel_count = 6,
9847 .num_mux_defs =
018df418
HM
9848 ARRAY_SIZE(alc889_capture_sources),
9849 .input_mux = alc889_capture_sources,
3b315d70 9850 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9851 .setup = alc889_acer_aspire_8930g_setup,
9852 .init_hook = alc_automute_amp,
f5de24b0 9853#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 9854 .power_hook = alc_power_eapd,
f5de24b0 9855#endif
3b315d70 9856 },
fc86f954
DK
9857 [ALC888_ACER_ASPIRE_7730G] = {
9858 .mixers = { alc883_3ST_6ch_mixer,
9859 alc883_chmode_mixer },
9860 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9861 alc888_acer_aspire_7730G_verbs },
9862 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9863 .dac_nids = alc883_dac_nids,
9864 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9865 .adc_nids = alc883_adc_nids_rev,
9866 .capsrc_nids = alc883_capsrc_nids_rev,
9867 .dig_out_nid = ALC883_DIGOUT_NID,
9868 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9869 .channel_mode = alc883_3ST_6ch_modes,
9870 .need_dac_fix = 1,
9871 .const_channel_count = 6,
9872 .input_mux = &alc883_capture_source,
9873 .unsol_event = alc_automute_amp_unsol_event,
9874 .setup = alc888_acer_aspire_6530g_setup,
9875 .init_hook = alc_automute_amp,
9876 },
c07584c8
TD
9877 [ALC883_MEDION] = {
9878 .mixers = { alc883_fivestack_mixer,
9879 alc883_chmode_mixer },
9880 .init_verbs = { alc883_init_verbs,
b373bdeb 9881 alc883_medion_eapd_verbs },
c07584c8
TD
9882 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9883 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9884 .adc_nids = alc883_adc_nids_alt,
9885 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9886 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
9887 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9888 .channel_mode = alc883_sixstack_modes,
9889 .input_mux = &alc883_capture_source,
b373bdeb 9890 },
272a527c
KY
9891 [ALC883_MEDION_MD2] = {
9892 .mixers = { alc883_medion_md2_mixer},
9893 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9894 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9895 .dac_nids = alc883_dac_nids,
9896 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9897 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9898 .channel_mode = alc883_3ST_2ch_modes,
9899 .input_mux = &alc883_capture_source,
a9fd4f3f 9900 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9901 .setup = alc883_medion_md2_setup,
9902 .init_hook = alc_automute_amp,
ea1fb29a 9903 },
b373bdeb 9904 [ALC883_LAPTOP_EAPD] = {
676a9b53 9905 .mixers = { alc883_base_mixer },
b373bdeb
AN
9906 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9907 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9908 .dac_nids = alc883_dac_nids,
b373bdeb
AN
9909 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9910 .channel_mode = alc883_3ST_2ch_modes,
9911 .input_mux = &alc883_capture_source,
9912 },
a65cc60f 9913 [ALC883_CLEVO_M540R] = {
9914 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9915 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9916 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9917 .dac_nids = alc883_dac_nids,
9918 .dig_out_nid = ALC883_DIGOUT_NID,
9919 .dig_in_nid = ALC883_DIGIN_NID,
9920 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9921 .channel_mode = alc883_3ST_6ch_clevo_modes,
9922 .need_dac_fix = 1,
9923 .input_mux = &alc883_capture_source,
9924 /* This machine has the hardware HP auto-muting, thus
9925 * we need no software mute via unsol event
9926 */
9927 },
0c4cc443
HRK
9928 [ALC883_CLEVO_M720] = {
9929 .mixers = { alc883_clevo_m720_mixer },
9930 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
9931 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9932 .dac_nids = alc883_dac_nids,
9933 .dig_out_nid = ALC883_DIGOUT_NID,
9934 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9935 .channel_mode = alc883_3ST_2ch_modes,
9936 .input_mux = &alc883_capture_source,
0c4cc443 9937 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 9938 .setup = alc883_clevo_m720_setup,
a9fd4f3f 9939 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 9940 },
bc9f98a9
KY
9941 [ALC883_LENOVO_101E_2ch] = {
9942 .mixers = { alc883_lenovo_101e_2ch_mixer},
9943 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9945 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9946 .adc_nids = alc883_adc_nids_alt,
9947 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9948 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
9949 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9950 .channel_mode = alc883_3ST_2ch_modes,
9951 .input_mux = &alc883_lenovo_101e_capture_source,
9952 .unsol_event = alc883_lenovo_101e_unsol_event,
9953 .init_hook = alc883_lenovo_101e_all_automute,
9954 },
272a527c
KY
9955 [ALC883_LENOVO_NB0763] = {
9956 .mixers = { alc883_lenovo_nb0763_mixer },
9957 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9958 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9959 .dac_nids = alc883_dac_nids,
272a527c
KY
9960 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9961 .channel_mode = alc883_3ST_2ch_modes,
9962 .need_dac_fix = 1,
9963 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 9964 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9965 .setup = alc883_medion_md2_setup,
9966 .init_hook = alc_automute_amp,
272a527c
KY
9967 },
9968 [ALC888_LENOVO_MS7195_DIG] = {
9969 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9970 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9972 .dac_nids = alc883_dac_nids,
9973 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9974 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9975 .channel_mode = alc883_3ST_6ch_modes,
9976 .need_dac_fix = 1,
9977 .input_mux = &alc883_capture_source,
9978 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9979 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
9980 },
9981 [ALC883_HAIER_W66] = {
c259249f 9982 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
9983 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9984 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9985 .dac_nids = alc883_dac_nids,
9986 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
9987 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9988 .channel_mode = alc883_3ST_2ch_modes,
9989 .input_mux = &alc883_capture_source,
a9fd4f3f 9990 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9991 .setup = alc883_haier_w66_setup,
9992 .init_hook = alc_automute_amp,
eea6419e 9993 },
4723c022 9994 [ALC888_3ST_HP] = {
eea6419e 9995 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 9996 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
9997 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9998 .dac_nids = alc883_dac_nids,
4723c022
CM
9999 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10000 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10001 .need_dac_fix = 1,
10002 .input_mux = &alc883_capture_source,
a9fd4f3f 10003 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10004 .setup = alc888_3st_hp_setup,
10005 .init_hook = alc_automute_amp,
8341de60 10006 },
5795b9e6 10007 [ALC888_6ST_DELL] = {
f24dbdc6 10008 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10009 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10010 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10011 .dac_nids = alc883_dac_nids,
10012 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10013 .dig_in_nid = ALC883_DIGIN_NID,
10014 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10015 .channel_mode = alc883_sixstack_modes,
10016 .input_mux = &alc883_capture_source,
a9fd4f3f 10017 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10018 .setup = alc888_6st_dell_setup,
10019 .init_hook = alc_automute_amp,
5795b9e6 10020 },
a8848bd6
AS
10021 [ALC883_MITAC] = {
10022 .mixers = { alc883_mitac_mixer },
10023 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10024 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10025 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10026 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10027 .channel_mode = alc883_3ST_2ch_modes,
10028 .input_mux = &alc883_capture_source,
a9fd4f3f 10029 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10030 .setup = alc883_mitac_setup,
10031 .init_hook = alc_automute_amp,
a8848bd6 10032 },
fb97dc67
J
10033 [ALC883_FUJITSU_PI2515] = {
10034 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10035 .init_verbs = { alc883_init_verbs,
10036 alc883_2ch_fujitsu_pi2515_verbs},
10037 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10038 .dac_nids = alc883_dac_nids,
10039 .dig_out_nid = ALC883_DIGOUT_NID,
10040 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10041 .channel_mode = alc883_3ST_2ch_modes,
10042 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10043 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10044 .setup = alc883_2ch_fujitsu_pi2515_setup,
10045 .init_hook = alc_automute_amp,
fb97dc67 10046 },
ef8ef5fb
VP
10047 [ALC888_FUJITSU_XA3530] = {
10048 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10049 .init_verbs = { alc883_init_verbs,
10050 alc888_fujitsu_xa3530_verbs },
10051 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10052 .dac_nids = alc883_dac_nids,
10053 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10054 .adc_nids = alc883_adc_nids_rev,
10055 .capsrc_nids = alc883_capsrc_nids_rev,
10056 .dig_out_nid = ALC883_DIGOUT_NID,
10057 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10058 .channel_mode = alc888_4ST_8ch_intel_modes,
10059 .num_mux_defs =
10060 ARRAY_SIZE(alc888_2_capture_sources),
10061 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10062 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10063 .setup = alc888_fujitsu_xa3530_setup,
10064 .init_hook = alc_automute_amp,
ef8ef5fb 10065 },
e2757d5e
KY
10066 [ALC888_LENOVO_SKY] = {
10067 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10068 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10069 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10070 .dac_nids = alc883_dac_nids,
10071 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10072 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10073 .channel_mode = alc883_sixstack_modes,
10074 .need_dac_fix = 1,
10075 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10076 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10077 .setup = alc888_lenovo_sky_setup,
10078 .init_hook = alc_automute_amp,
e2757d5e
KY
10079 },
10080 [ALC888_ASUS_M90V] = {
10081 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10082 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10083 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10084 .dac_nids = alc883_dac_nids,
10085 .dig_out_nid = ALC883_DIGOUT_NID,
10086 .dig_in_nid = ALC883_DIGIN_NID,
10087 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10088 .channel_mode = alc883_3ST_6ch_modes,
10089 .need_dac_fix = 1,
10090 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10091 .unsol_event = alc_sku_unsol_event,
10092 .setup = alc883_mode2_setup,
10093 .init_hook = alc_inithook,
e2757d5e
KY
10094 },
10095 [ALC888_ASUS_EEE1601] = {
10096 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10097 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10098 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10099 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10100 .dac_nids = alc883_dac_nids,
10101 .dig_out_nid = ALC883_DIGOUT_NID,
10102 .dig_in_nid = ALC883_DIGIN_NID,
10103 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10104 .channel_mode = alc883_3ST_2ch_modes,
10105 .need_dac_fix = 1,
10106 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10107 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10108 .init_hook = alc883_eee1601_inithook,
10109 },
3ab90935
WF
10110 [ALC1200_ASUS_P5Q] = {
10111 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10112 .init_verbs = { alc883_init_verbs },
10113 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10114 .dac_nids = alc883_dac_nids,
10115 .dig_out_nid = ALC1200_DIGOUT_NID,
10116 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10117 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10118 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10119 .channel_mode = alc883_sixstack_modes,
10120 .input_mux = &alc883_capture_source,
10121 },
eb4c41d3
TS
10122 [ALC889A_MB31] = {
10123 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10124 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10125 alc880_gpio1_init_verbs },
10126 .adc_nids = alc883_adc_nids,
10127 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10128 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10129 .dac_nids = alc883_dac_nids,
10130 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10131 .channel_mode = alc889A_mb31_6ch_modes,
10132 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10133 .input_mux = &alc889A_mb31_capture_source,
10134 .dig_out_nid = ALC883_DIGOUT_NID,
10135 .unsol_event = alc889A_mb31_unsol_event,
10136 .init_hook = alc889A_mb31_automute,
10137 },
3e1647c5
GG
10138 [ALC883_SONY_VAIO_TT] = {
10139 .mixers = { alc883_vaiott_mixer },
10140 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10141 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10142 .dac_nids = alc883_dac_nids,
10143 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10144 .channel_mode = alc883_3ST_2ch_modes,
10145 .input_mux = &alc883_capture_source,
10146 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10147 .setup = alc883_vaiott_setup,
10148 .init_hook = alc_automute_amp,
3e1647c5 10149 },
9c7f852e
TI
10150};
10151
10152
4953550a
TI
10153/*
10154 * Pin config fixes
10155 */
10156enum {
10157 PINFIX_ABIT_AW9D_MAX
10158};
10159
10160static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10161 { 0x15, 0x01080104 }, /* side */
10162 { 0x16, 0x01011012 }, /* rear */
10163 { 0x17, 0x01016011 }, /* clfe */
10164 { }
10165};
10166
f8f25ba3
TI
10167static const struct alc_fixup alc882_fixups[] = {
10168 [PINFIX_ABIT_AW9D_MAX] = {
10169 .pins = alc882_abit_aw9d_pinfix
10170 },
4953550a
TI
10171};
10172
f8f25ba3 10173static struct snd_pci_quirk alc882_fixup_tbl[] = {
4953550a
TI
10174 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10175 {}
10176};
10177
9c7f852e
TI
10178/*
10179 * BIOS auto configuration
10180 */
05f5f477
TI
10181static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10182 const struct auto_pin_cfg *cfg)
10183{
10184 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10185}
10186
4953550a 10187static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e
TI
10188 hda_nid_t nid, int pin_type,
10189 int dac_idx)
10190{
10191 /* set as output */
10192 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
10193 int idx;
10194
f6c7e546 10195 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
10196 if (spec->multiout.dac_nids[dac_idx] == 0x25)
10197 idx = 4;
6a4f2ccb
TI
10198 else {
10199 if (spec->multiout.num_dacs >= dac_idx)
10200 return;
9c7f852e 10201 idx = spec->multiout.dac_nids[dac_idx] - 2;
6a4f2ccb 10202 }
9c7f852e
TI
10203 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10204
10205}
10206
4953550a 10207static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10208{
10209 struct alc_spec *spec = codec->spec;
10210 int i;
10211
10212 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10213 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10214 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10215 if (nid)
4953550a 10216 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 10217 i);
9c7f852e
TI
10218 }
10219}
10220
4953550a 10221static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10222{
10223 struct alc_spec *spec = codec->spec;
10224 hda_nid_t pin;
10225
eb06ed8f 10226 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
10227 if (pin) /* connect to front */
10228 /* use dac 0 */
4953550a 10229 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
10230 pin = spec->autocfg.speaker_pins[0];
10231 if (pin)
4953550a 10232 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
10233}
10234
4953550a 10235static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10236{
10237 struct alc_spec *spec = codec->spec;
10238 int i;
10239
10240 for (i = 0; i < AUTO_PIN_LAST; i++) {
10241 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10242 if (!nid)
10243 continue;
0d971c9f 10244 alc_set_input_pin(codec, nid, i);
4953550a
TI
10245 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10246 snd_hda_codec_write(codec, nid, 0,
10247 AC_VERB_SET_AMP_GAIN_MUTE,
10248 AMP_OUT_MUTE);
10249 }
10250}
10251
10252static void alc882_auto_init_input_src(struct hda_codec *codec)
10253{
10254 struct alc_spec *spec = codec->spec;
10255 int c;
10256
10257 for (c = 0; c < spec->num_adc_nids; c++) {
10258 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10259 hda_nid_t nid = spec->capsrc_nids[c];
10260 unsigned int mux_idx;
10261 const struct hda_input_mux *imux;
10262 int conns, mute, idx, item;
10263
10264 conns = snd_hda_get_connections(codec, nid, conn_list,
10265 ARRAY_SIZE(conn_list));
10266 if (conns < 0)
10267 continue;
10268 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10269 imux = &spec->input_mux[mux_idx];
5311114d
TI
10270 if (!imux->num_items && mux_idx > 0)
10271 imux = &spec->input_mux[0];
4953550a
TI
10272 for (idx = 0; idx < conns; idx++) {
10273 /* if the current connection is the selected one,
10274 * unmute it as default - otherwise mute it
10275 */
10276 mute = AMP_IN_MUTE(idx);
10277 for (item = 0; item < imux->num_items; item++) {
10278 if (imux->items[item].index == idx) {
10279 if (spec->cur_mux[c] == item)
10280 mute = AMP_IN_UNMUTE(idx);
10281 break;
10282 }
10283 }
10284 /* check if we have a selector or mixer
10285 * we could check for the widget type instead, but
10286 * just check for Amp-In presence (in case of mixer
10287 * without amp-in there is something wrong, this
10288 * function shouldn't be used or capsrc nid is wrong)
10289 */
10290 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10291 snd_hda_codec_write(codec, nid, 0,
10292 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10293 mute);
10294 else if (mute != AMP_IN_MUTE(idx))
10295 snd_hda_codec_write(codec, nid, 0,
10296 AC_VERB_SET_CONNECT_SEL,
10297 idx);
9c7f852e
TI
10298 }
10299 }
10300}
10301
4953550a
TI
10302/* add mic boosts if needed */
10303static int alc_auto_add_mic_boost(struct hda_codec *codec)
10304{
10305 struct alc_spec *spec = codec->spec;
10306 int err;
10307 hda_nid_t nid;
10308
10309 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10310 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10311 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10312 "Mic Boost",
10313 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10314 if (err < 0)
10315 return err;
10316 }
10317 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10318 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10319 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10320 "Front Mic Boost",
10321 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10322 if (err < 0)
10323 return err;
10324 }
10325 return 0;
10326}
f511b01c 10327
9c7f852e 10328/* almost identical with ALC880 parser... */
4953550a 10329static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10330{
10331 struct alc_spec *spec = codec->spec;
05f5f477
TI
10332 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10333 int i, err;
9c7f852e 10334
05f5f477
TI
10335 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10336 alc882_ignore);
9c7f852e
TI
10337 if (err < 0)
10338 return err;
05f5f477
TI
10339 if (!spec->autocfg.line_outs)
10340 return 0; /* can't find valid BIOS pin config */
776e184e 10341
05f5f477
TI
10342 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10343 if (err < 0)
10344 return err;
10345 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10346 if (err < 0)
10347 return err;
10348 err = alc880_auto_create_extra_out(spec,
10349 spec->autocfg.speaker_pins[0],
10350 "Speaker");
10351 if (err < 0)
10352 return err;
10353 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10354 "Headphone");
10355 if (err < 0)
10356 return err;
10357 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10358 if (err < 0)
10359 return err;
10360
05f5f477
TI
10361 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10362
10363 /* check multiple SPDIF-out (for recent codecs) */
10364 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10365 hda_nid_t dig_nid;
10366 err = snd_hda_get_connections(codec,
10367 spec->autocfg.dig_out_pins[i],
10368 &dig_nid, 1);
10369 if (err < 0)
10370 continue;
10371 if (!i)
10372 spec->multiout.dig_out_nid = dig_nid;
10373 else {
10374 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 10375 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
05f5f477 10376 break;
71121d9f 10377 spec->slave_dig_outs[i - 1] = dig_nid;
05f5f477
TI
10378 }
10379 }
10380 if (spec->autocfg.dig_in_pin)
10381 spec->dig_in_nid = ALC880_DIGIN_NID;
10382
10383 if (spec->kctls.list)
10384 add_mixer(spec, spec->kctls.list);
10385
10386 add_verb(spec, alc883_auto_init_verbs);
4953550a 10387 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10388 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10389 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10390
05f5f477
TI
10391 spec->num_mux_defs = 1;
10392 spec->input_mux = &spec->private_imux[0];
10393
6227cdce 10394 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10395
10396 err = alc_auto_add_mic_boost(codec);
10397 if (err < 0)
10398 return err;
61b9b9b1 10399
776e184e 10400 return 1; /* config found */
9c7f852e
TI
10401}
10402
10403/* additional initialization for auto-configuration model */
4953550a 10404static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10405{
f6c7e546 10406 struct alc_spec *spec = codec->spec;
4953550a
TI
10407 alc882_auto_init_multi_out(codec);
10408 alc882_auto_init_hp_out(codec);
10409 alc882_auto_init_analog_input(codec);
10410 alc882_auto_init_input_src(codec);
f6c7e546 10411 if (spec->unsol_event)
7fb0d78f 10412 alc_inithook(codec);
9c7f852e
TI
10413}
10414
4953550a 10415static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10416{
10417 struct alc_spec *spec;
10418 int err, board_config;
10419
10420 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10421 if (spec == NULL)
10422 return -ENOMEM;
10423
10424 codec->spec = spec;
10425
da00c244
KY
10426 alc_auto_parse_customize_define(codec);
10427
4953550a
TI
10428 switch (codec->vendor_id) {
10429 case 0x10ec0882:
10430 case 0x10ec0885:
10431 break;
10432 default:
10433 /* ALC883 and variants */
10434 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10435 break;
10436 }
2c3bf9ab 10437
4953550a
TI
10438 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10439 alc882_models,
10440 alc882_cfg_tbl);
10441
10442 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10443 board_config = snd_hda_check_board_codec_sid_config(codec,
10444 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10445
10446 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10447 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10448 codec->chip_name);
10449 board_config = ALC882_AUTO;
9c7f852e
TI
10450 }
10451
f8f25ba3 10452 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
4953550a
TI
10453
10454 if (board_config == ALC882_AUTO) {
9c7f852e 10455 /* automatic parse from the BIOS config */
4953550a 10456 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10457 if (err < 0) {
10458 alc_free(codec);
10459 return err;
f12ab1e0 10460 } else if (!err) {
9c7f852e
TI
10461 printk(KERN_INFO
10462 "hda_codec: Cannot set up configuration "
10463 "from BIOS. Using base mode...\n");
4953550a 10464 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10465 }
10466 }
10467
680cd536
KK
10468 err = snd_hda_attach_beep_device(codec, 0x1);
10469 if (err < 0) {
10470 alc_free(codec);
10471 return err;
10472 }
10473
4953550a 10474 if (board_config != ALC882_AUTO)
e9c364c0 10475 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10476
4953550a
TI
10477 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10478 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10479 /* FIXME: setup DAC5 */
10480 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10481 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10482
10483 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10484 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10485
10486 if (codec->vendor_id == 0x10ec0888)
4a79ba34 10487 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
4953550a
TI
10488
10489 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10490 int i, j;
4953550a
TI
10491 spec->num_adc_nids = 0;
10492 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10493 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10494 hda_nid_t cap;
d11f74c6 10495 hda_nid_t items[16];
4953550a
TI
10496 hda_nid_t nid = alc882_adc_nids[i];
10497 unsigned int wcap = get_wcaps(codec, nid);
10498 /* get type */
a22d543a 10499 wcap = get_wcaps_type(wcap);
4953550a
TI
10500 if (wcap != AC_WID_AUD_IN)
10501 continue;
10502 spec->private_adc_nids[spec->num_adc_nids] = nid;
10503 err = snd_hda_get_connections(codec, nid, &cap, 1);
10504 if (err < 0)
10505 continue;
d11f74c6
TI
10506 err = snd_hda_get_connections(codec, cap, items,
10507 ARRAY_SIZE(items));
10508 if (err < 0)
10509 continue;
10510 for (j = 0; j < imux->num_items; j++)
10511 if (imux->items[j].index >= err)
10512 break;
10513 if (j < imux->num_items)
10514 continue;
4953550a
TI
10515 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10516 spec->num_adc_nids++;
61b9b9b1 10517 }
4953550a
TI
10518 spec->adc_nids = spec->private_adc_nids;
10519 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10520 }
10521
b59bdf3b 10522 set_capture_mixer(codec);
da00c244
KY
10523
10524 if (spec->cdefine.enable_pcbeep)
10525 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10526
2134ea4f
TI
10527 spec->vmaster_nid = 0x0c;
10528
9c7f852e 10529 codec->patch_ops = alc_patch_ops;
4953550a
TI
10530 if (board_config == ALC882_AUTO)
10531 spec->init_hook = alc882_auto_init;
cb53c626
TI
10532#ifdef CONFIG_SND_HDA_POWER_SAVE
10533 if (!spec->loopback.amplist)
4953550a 10534 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10535#endif
9c7f852e
TI
10536
10537 return 0;
10538}
10539
4953550a 10540
9c7f852e
TI
10541/*
10542 * ALC262 support
10543 */
10544
10545#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10546#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10547
10548#define alc262_dac_nids alc260_dac_nids
10549#define alc262_adc_nids alc882_adc_nids
10550#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10551#define alc262_capsrc_nids alc882_capsrc_nids
10552#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10553
10554#define alc262_modes alc260_modes
10555#define alc262_capture_source alc882_capture_source
10556
4e555fe5
KY
10557static hda_nid_t alc262_dmic_adc_nids[1] = {
10558 /* ADC0 */
10559 0x09
10560};
10561
10562static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10563
9c7f852e
TI
10564static struct snd_kcontrol_new alc262_base_mixer[] = {
10565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10566 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10567 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10568 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10569 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10570 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10571 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10572 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10573 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10574 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10575 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10576 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10577 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10578 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10579 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10580 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10581 { } /* end */
10582};
10583
ce875f07
TI
10584/* update HP, line and mono-out pins according to the master switch */
10585static void alc262_hp_master_update(struct hda_codec *codec)
10586{
10587 struct alc_spec *spec = codec->spec;
10588 int val = spec->master_sw;
10589
10590 /* HP & line-out */
10591 snd_hda_codec_write_cache(codec, 0x1b, 0,
10592 AC_VERB_SET_PIN_WIDGET_CONTROL,
10593 val ? PIN_HP : 0);
10594 snd_hda_codec_write_cache(codec, 0x15, 0,
10595 AC_VERB_SET_PIN_WIDGET_CONTROL,
10596 val ? PIN_HP : 0);
10597 /* mono (speaker) depending on the HP jack sense */
10598 val = val && !spec->jack_present;
10599 snd_hda_codec_write_cache(codec, 0x16, 0,
10600 AC_VERB_SET_PIN_WIDGET_CONTROL,
10601 val ? PIN_OUT : 0);
10602}
10603
10604static void alc262_hp_bpc_automute(struct hda_codec *codec)
10605{
10606 struct alc_spec *spec = codec->spec;
864f92be
WF
10607
10608 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10609 alc262_hp_master_update(codec);
10610}
10611
10612static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10613{
10614 if ((res >> 26) != ALC880_HP_EVENT)
10615 return;
10616 alc262_hp_bpc_automute(codec);
10617}
10618
10619static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10620{
10621 struct alc_spec *spec = codec->spec;
864f92be
WF
10622
10623 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10624 alc262_hp_master_update(codec);
10625}
10626
10627static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10628 unsigned int res)
10629{
10630 if ((res >> 26) != ALC880_HP_EVENT)
10631 return;
10632 alc262_hp_wildwest_automute(codec);
10633}
10634
b72519b5 10635#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10636
10637static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10638 struct snd_ctl_elem_value *ucontrol)
10639{
10640 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10641 struct alc_spec *spec = codec->spec;
10642 int val = !!*ucontrol->value.integer.value;
10643
10644 if (val == spec->master_sw)
10645 return 0;
10646 spec->master_sw = val;
10647 alc262_hp_master_update(codec);
10648 return 1;
10649}
10650
b72519b5
TI
10651#define ALC262_HP_MASTER_SWITCH \
10652 { \
10653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10654 .name = "Master Playback Switch", \
10655 .info = snd_ctl_boolean_mono_info, \
10656 .get = alc262_hp_master_sw_get, \
10657 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10658 }, \
10659 { \
10660 .iface = NID_MAPPING, \
10661 .name = "Master Playback Switch", \
10662 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10663 }
10664
5b0cb1d8 10665
9c7f852e 10666static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10667 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10668 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10669 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10670 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10671 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10672 HDA_OUTPUT),
10673 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10674 HDA_OUTPUT),
9c7f852e
TI
10675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10676 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10677 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10680 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10681 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10682 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10683 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10684 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10685 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10686 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10687 { } /* end */
10688};
10689
cd7509a4 10690static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10691 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10692 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10693 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10695 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10696 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10697 HDA_OUTPUT),
10698 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10699 HDA_OUTPUT),
cd7509a4
KY
10700 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10701 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10702 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10703 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10704 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10705 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10706 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10707 { } /* end */
10708};
10709
10710static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10711 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10712 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10713 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10714 { } /* end */
10715};
10716
66d2a9d6 10717/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10718static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10719{
10720 struct alc_spec *spec = codec->spec;
66d2a9d6 10721
a9fd4f3f 10722 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10723 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10724}
10725
66d2a9d6 10726static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10727 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10728 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10729 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10730 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10733 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10734 { } /* end */
10735};
10736
10737static struct hda_verb alc262_hp_t5735_verbs[] = {
10738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10739 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10740
10741 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10742 { }
10743};
10744
8c427226 10745static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
10746 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
10748 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10749 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
10750 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10751 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10752 { } /* end */
10753};
10754
10755static struct hda_verb alc262_hp_rp5700_verbs[] = {
10756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10758 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10760 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10761 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10766 {}
10767};
10768
10769static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10770 .num_items = 1,
10771 .items = {
10772 { "Line", 0x1 },
10773 },
10774};
10775
42171c17
TI
10776/* bind hp and internal speaker mute (with plug check) as master switch */
10777static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 10778{
42171c17
TI
10779 struct alc_spec *spec = codec->spec;
10780 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10781 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10782 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10783 unsigned int mute;
0724ea2a 10784
42171c17
TI
10785 /* HP */
10786 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10787 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10788 HDA_AMP_MUTE, mute);
10789 /* mute internal speaker per jack sense */
10790 if (spec->jack_present)
10791 mute = HDA_AMP_MUTE;
10792 if (line_nid)
10793 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10794 HDA_AMP_MUTE, mute);
10795 if (speaker_nid && speaker_nid != line_nid)
10796 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 10797 HDA_AMP_MUTE, mute);
42171c17
TI
10798}
10799
10800#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10801
10802static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10803 struct snd_ctl_elem_value *ucontrol)
10804{
10805 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10806 struct alc_spec *spec = codec->spec;
10807 int val = !!*ucontrol->value.integer.value;
10808
10809 if (val == spec->master_sw)
10810 return 0;
10811 spec->master_sw = val;
10812 alc262_hippo_master_update(codec);
10813 return 1;
10814}
10815
10816#define ALC262_HIPPO_MASTER_SWITCH \
10817 { \
10818 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10819 .name = "Master Playback Switch", \
10820 .info = snd_ctl_boolean_mono_info, \
10821 .get = alc262_hippo_master_sw_get, \
10822 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
10823 }, \
10824 { \
10825 .iface = NID_MAPPING, \
10826 .name = "Master Playback Switch", \
10827 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10828 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 10829 }
42171c17
TI
10830
10831static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10832 ALC262_HIPPO_MASTER_SWITCH,
10833 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10834 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10835 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10836 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10837 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10838 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10839 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10840 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10841 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10843 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10844 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10845 { } /* end */
10846};
10847
10848static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10849 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10850 ALC262_HIPPO_MASTER_SWITCH,
10851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10852 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10857 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10858 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10859 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10860 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10861 { } /* end */
10862};
10863
10864/* mute/unmute internal speaker according to the hp jack and mute state */
10865static void alc262_hippo_automute(struct hda_codec *codec)
10866{
10867 struct alc_spec *spec = codec->spec;
10868 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 10869
864f92be 10870 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 10871 alc262_hippo_master_update(codec);
0724ea2a 10872}
5b31954e 10873
42171c17
TI
10874static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10875{
10876 if ((res >> 26) != ALC880_HP_EVENT)
10877 return;
10878 alc262_hippo_automute(codec);
10879}
10880
4f5d1706 10881static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
10882{
10883 struct alc_spec *spec = codec->spec;
10884
10885 spec->autocfg.hp_pins[0] = 0x15;
10886 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10887}
10888
4f5d1706 10889static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
10890{
10891 struct alc_spec *spec = codec->spec;
10892
10893 spec->autocfg.hp_pins[0] = 0x1b;
10894 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10895}
10896
10897
272a527c 10898static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 10899 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 10900 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
10901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10903 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10904 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10905 { } /* end */
10906};
10907
83c34218 10908static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
10909 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10910 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
10911 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10914 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10915 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10916 { } /* end */
10917};
272a527c 10918
ba340e82
TV
10919static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10920 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10921 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10922 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10923 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10924 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10925 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10926 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10927 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10928 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10929 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10930 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10931 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10932 { } /* end */
10933};
10934
10935static struct hda_verb alc262_tyan_verbs[] = {
10936 /* Headphone automute */
10937 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10940
10941 /* P11 AUX_IN, white 4-pin connector */
10942 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10943 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10944 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10945 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10946
10947 {}
10948};
10949
10950/* unsolicited event for HP jack sensing */
4f5d1706 10951static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 10952{
a9fd4f3f 10953 struct alc_spec *spec = codec->spec;
ba340e82 10954
a9fd4f3f
TI
10955 spec->autocfg.hp_pins[0] = 0x1b;
10956 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
10957}
10958
ba340e82 10959
9c7f852e
TI
10960#define alc262_capture_mixer alc882_capture_mixer
10961#define alc262_capture_alt_mixer alc882_capture_alt_mixer
10962
10963/*
10964 * generic initialization of ADC, input mixers and output mixers
10965 */
10966static struct hda_verb alc262_init_verbs[] = {
10967 /*
10968 * Unmute ADC0-2 and set the default input to mic-in
10969 */
10970 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10972 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10976
cb53c626 10977 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10978 * mixer widget
f12ab1e0
TI
10979 * Note: PASD motherboards uses the Line In 2 as the input for
10980 * front panel mic (mic 2)
9c7f852e
TI
10981 */
10982 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
10988
10989 /*
df694daa
KY
10990 * Set up output mixers (0x0c - 0x0e)
10991 */
10992 /* set vol=0 to output mixers */
10993 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10994 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10996 /* set up input amps for analog loopback */
10997 /* Amp Indices: DAC = 0, mixer = 1 */
10998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11000 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11001 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11003 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11004
11005 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11007 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11008 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11009 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11010 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11011
11012 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11014 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11015 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11016 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11017
df694daa
KY
11018 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11019 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11020
df694daa
KY
11021 /* FIXME: use matrix-type input source selection */
11022 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11023 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11028 /* Input mixer2 */
11029 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11030 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11031 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11032 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11033 /* Input mixer3 */
11034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11038
11039 { }
11040};
1da177e4 11041
4e555fe5
KY
11042static struct hda_verb alc262_eapd_verbs[] = {
11043 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11044 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11045 { }
11046};
11047
ccc656ce
KY
11048static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11049 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11050 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11051 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11052
11053 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11054 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11055 {}
11056};
11057
272a527c
KY
11058static struct hda_verb alc262_sony_unsol_verbs[] = {
11059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11061 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11062
11063 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11065 {}
272a527c
KY
11066};
11067
4e555fe5
KY
11068static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11069 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11070 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11074 { } /* end */
11075};
11076
11077static struct hda_verb alc262_toshiba_s06_verbs[] = {
11078 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11079 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11080 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11081 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11082 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11083 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11084 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11085 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11086 {}
11087};
11088
4f5d1706 11089static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11090{
a9fd4f3f
TI
11091 struct alc_spec *spec = codec->spec;
11092
11093 spec->autocfg.hp_pins[0] = 0x15;
11094 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11095 spec->ext_mic.pin = 0x18;
11096 spec->ext_mic.mux_idx = 0;
11097 spec->int_mic.pin = 0x12;
11098 spec->int_mic.mux_idx = 9;
11099 spec->auto_mic = 1;
4e555fe5
KY
11100}
11101
e8f9ae2a
PT
11102/*
11103 * nec model
11104 * 0x15 = headphone
11105 * 0x16 = internal speaker
11106 * 0x18 = external mic
11107 */
11108
11109static struct snd_kcontrol_new alc262_nec_mixer[] = {
11110 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11111 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11112
11113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11116
11117 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11119 { } /* end */
11120};
11121
11122static struct hda_verb alc262_nec_verbs[] = {
11123 /* Unmute Speaker */
11124 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11125
11126 /* Headphone */
11127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11128 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11129
11130 /* External mic to headphone */
11131 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11132 /* External mic to speaker */
11133 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11134 {}
11135};
11136
834be88d
TI
11137/*
11138 * fujitsu model
5d9fab2d
TV
11139 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11140 * 0x1b = port replicator headphone out
834be88d
TI
11141 */
11142
11143#define ALC_HP_EVENT 0x37
11144
11145static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11146 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11148 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11150 {}
11151};
11152
0e31daf7
J
11153static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11154 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11155 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11156 {}
11157};
11158
e2595322
DC
11159static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11160 /* Front Mic pin: input vref at 50% */
11161 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11162 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11163 {}
11164};
11165
834be88d 11166static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11167 .num_items = 3,
834be88d
TI
11168 .items = {
11169 { "Mic", 0x0 },
39d3ed38 11170 { "Int Mic", 0x1 },
834be88d
TI
11171 { "CD", 0x4 },
11172 },
11173};
11174
9c7f852e
TI
11175static struct hda_input_mux alc262_HP_capture_source = {
11176 .num_items = 5,
11177 .items = {
11178 { "Mic", 0x0 },
accbe498 11179 { "Front Mic", 0x1 },
9c7f852e
TI
11180 { "Line", 0x2 },
11181 { "CD", 0x4 },
11182 { "AUX IN", 0x6 },
11183 },
11184};
11185
accbe498 11186static struct hda_input_mux alc262_HP_D7000_capture_source = {
11187 .num_items = 4,
11188 .items = {
11189 { "Mic", 0x0 },
11190 { "Front Mic", 0x2 },
11191 { "Line", 0x1 },
11192 { "CD", 0x4 },
11193 },
11194};
11195
ebc7a406 11196/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11197static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11198{
11199 struct alc_spec *spec = codec->spec;
11200 unsigned int mute;
11201
f12ab1e0 11202 if (force || !spec->sense_updated) {
864f92be
WF
11203 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11204 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11205 spec->sense_updated = 1;
11206 }
ebc7a406
TI
11207 /* unmute internal speaker only if both HPs are unplugged and
11208 * master switch is on
11209 */
11210 if (spec->jack_present)
11211 mute = HDA_AMP_MUTE;
11212 else
834be88d 11213 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11214 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11215 HDA_AMP_MUTE, mute);
834be88d
TI
11216}
11217
11218/* unsolicited event for HP jack sensing */
11219static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11220 unsigned int res)
11221{
11222 if ((res >> 26) != ALC_HP_EVENT)
11223 return;
11224 alc262_fujitsu_automute(codec, 1);
11225}
11226
ebc7a406
TI
11227static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11228{
11229 alc262_fujitsu_automute(codec, 1);
11230}
11231
834be88d 11232/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11233static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11234 .ops = &snd_hda_bind_vol,
11235 .values = {
11236 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11237 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11238 0
11239 },
11240};
834be88d 11241
0e31daf7
J
11242/* mute/unmute internal speaker according to the hp jack and mute state */
11243static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11244{
11245 struct alc_spec *spec = codec->spec;
11246 unsigned int mute;
11247
11248 if (force || !spec->sense_updated) {
864f92be 11249 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11250 spec->sense_updated = 1;
11251 }
11252 if (spec->jack_present) {
11253 /* mute internal speaker */
11254 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11255 HDA_AMP_MUTE, HDA_AMP_MUTE);
11256 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11257 HDA_AMP_MUTE, HDA_AMP_MUTE);
11258 } else {
11259 /* unmute internal speaker if necessary */
11260 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11261 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11262 HDA_AMP_MUTE, mute);
11263 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11264 HDA_AMP_MUTE, mute);
11265 }
11266}
11267
11268/* unsolicited event for HP jack sensing */
11269static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11270 unsigned int res)
11271{
11272 if ((res >> 26) != ALC_HP_EVENT)
11273 return;
11274 alc262_lenovo_3000_automute(codec, 1);
11275}
11276
8de56b7d
TI
11277static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11278 int dir, int idx, long *valp)
11279{
11280 int i, change = 0;
11281
11282 for (i = 0; i < 2; i++, valp++)
11283 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11284 HDA_AMP_MUTE,
11285 *valp ? 0 : HDA_AMP_MUTE);
11286 return change;
11287}
11288
834be88d
TI
11289/* bind hp and internal speaker mute (with plug check) */
11290static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11291 struct snd_ctl_elem_value *ucontrol)
11292{
11293 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11294 long *valp = ucontrol->value.integer.value;
11295 int change;
11296
8de56b7d
TI
11297 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11298 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11299 if (change)
11300 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11301 return change;
11302}
11303
11304static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11305 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11306 {
11307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11308 .name = "Master Playback Switch",
5e26dfd0 11309 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11310 .info = snd_hda_mixer_amp_switch_info,
11311 .get = snd_hda_mixer_amp_switch_get,
11312 .put = alc262_fujitsu_master_sw_put,
11313 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11314 },
5b0cb1d8
JK
11315 {
11316 .iface = NID_MAPPING,
11317 .name = "Master Playback Switch",
11318 .private_value = 0x1b,
11319 },
834be88d
TI
11320 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11321 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11325 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11326 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11327 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11328 { } /* end */
11329};
11330
0e31daf7
J
11331/* bind hp and internal speaker mute (with plug check) */
11332static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11333 struct snd_ctl_elem_value *ucontrol)
11334{
11335 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11336 long *valp = ucontrol->value.integer.value;
11337 int change;
11338
8de56b7d 11339 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11340 if (change)
11341 alc262_lenovo_3000_automute(codec, 0);
11342 return change;
11343}
11344
11345static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11346 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11347 {
11348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11349 .name = "Master Playback Switch",
5e26dfd0 11350 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11351 .info = snd_hda_mixer_amp_switch_info,
11352 .get = snd_hda_mixer_amp_switch_get,
11353 .put = alc262_lenovo_3000_master_sw_put,
11354 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11355 },
11356 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11357 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11358 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11361 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11362 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11363 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11364 { } /* end */
11365};
11366
9f99a638
HM
11367static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11368 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11369 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11373 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11374 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11375 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11376 { } /* end */
11377};
11378
304dcaac
TI
11379/* additional init verbs for Benq laptops */
11380static struct hda_verb alc262_EAPD_verbs[] = {
11381 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11382 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11383 {}
11384};
11385
83c34218
KY
11386static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11387 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11389
11390 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11391 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11392 {}
11393};
11394
f651b50b
TD
11395/* Samsung Q1 Ultra Vista model setup */
11396static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11397 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11398 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11399 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11401 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11402 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11403 { } /* end */
11404};
11405
11406static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11407 /* output mixer */
11408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11411 /* speaker */
11412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11413 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11414 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11415 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11416 /* HP */
f651b50b 11417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11419 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11420 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11421 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11422 /* internal mic */
11423 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11425 /* ADC, choose mic */
11426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11429 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11430 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11436 {}
11437};
11438
f651b50b
TD
11439/* mute/unmute internal speaker according to the hp jack and mute state */
11440static void alc262_ultra_automute(struct hda_codec *codec)
11441{
11442 struct alc_spec *spec = codec->spec;
11443 unsigned int mute;
f651b50b 11444
bb9f76cd
TI
11445 mute = 0;
11446 /* auto-mute only when HP is used as HP */
11447 if (!spec->cur_mux[0]) {
864f92be 11448 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11449 if (spec->jack_present)
11450 mute = HDA_AMP_MUTE;
f651b50b 11451 }
bb9f76cd
TI
11452 /* mute/unmute internal speaker */
11453 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11454 HDA_AMP_MUTE, mute);
11455 /* mute/unmute HP */
11456 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11457 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11458}
11459
11460/* unsolicited event for HP jack sensing */
11461static void alc262_ultra_unsol_event(struct hda_codec *codec,
11462 unsigned int res)
11463{
11464 if ((res >> 26) != ALC880_HP_EVENT)
11465 return;
11466 alc262_ultra_automute(codec);
11467}
11468
bb9f76cd
TI
11469static struct hda_input_mux alc262_ultra_capture_source = {
11470 .num_items = 2,
11471 .items = {
11472 { "Mic", 0x1 },
11473 { "Headphone", 0x7 },
11474 },
11475};
11476
11477static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11478 struct snd_ctl_elem_value *ucontrol)
11479{
11480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11481 struct alc_spec *spec = codec->spec;
11482 int ret;
11483
54cbc9ab 11484 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11485 if (!ret)
11486 return 0;
11487 /* reprogram the HP pin as mic or HP according to the input source */
11488 snd_hda_codec_write_cache(codec, 0x15, 0,
11489 AC_VERB_SET_PIN_WIDGET_CONTROL,
11490 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11491 alc262_ultra_automute(codec); /* mute/unmute HP */
11492 return ret;
11493}
11494
11495static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11496 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11497 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11498 {
11499 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11500 .name = "Capture Source",
54cbc9ab
TI
11501 .info = alc_mux_enum_info,
11502 .get = alc_mux_enum_get,
bb9f76cd
TI
11503 .put = alc262_ultra_mux_enum_put,
11504 },
5b0cb1d8
JK
11505 {
11506 .iface = NID_MAPPING,
11507 .name = "Capture Source",
11508 .private_value = 0x15,
11509 },
bb9f76cd
TI
11510 { } /* end */
11511};
11512
c3fc1f50
TI
11513/* We use two mixers depending on the output pin; 0x16 is a mono output
11514 * and thus it's bound with a different mixer.
11515 * This function returns which mixer amp should be used.
11516 */
11517static int alc262_check_volbit(hda_nid_t nid)
11518{
11519 if (!nid)
11520 return 0;
11521 else if (nid == 0x16)
11522 return 2;
11523 else
11524 return 1;
11525}
11526
11527static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11528 const char *pfx, int *vbits)
11529{
c3fc1f50
TI
11530 unsigned long val;
11531 int vbit;
11532
11533 vbit = alc262_check_volbit(nid);
11534 if (!vbit)
11535 return 0;
11536 if (*vbits & vbit) /* a volume control for this mixer already there */
11537 return 0;
11538 *vbits |= vbit;
c3fc1f50
TI
11539 if (vbit == 2)
11540 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11541 else
11542 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11543 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11544}
11545
11546static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11547 const char *pfx)
11548{
c3fc1f50
TI
11549 unsigned long val;
11550
11551 if (!nid)
11552 return 0;
c3fc1f50
TI
11553 if (nid == 0x16)
11554 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11555 else
11556 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11557 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11558}
11559
df694daa 11560/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11561static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11562 const struct auto_pin_cfg *cfg)
df694daa 11563{
c3fc1f50
TI
11564 const char *pfx;
11565 int vbits;
df694daa
KY
11566 int err;
11567
11568 spec->multiout.num_dacs = 1; /* only use one dac */
11569 spec->multiout.dac_nids = spec->private_dac_nids;
11570 spec->multiout.dac_nids[0] = 2;
11571
c3fc1f50
TI
11572 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11573 pfx = "Master";
11574 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11575 pfx = "Speaker";
11576 else
11577 pfx = "Front";
11578 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11579 if (err < 0)
11580 return err;
11581 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11582 if (err < 0)
11583 return err;
11584 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11585 if (err < 0)
11586 return err;
df694daa 11587
c3fc1f50
TI
11588 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11589 alc262_check_volbit(cfg->speaker_pins[0]) |
11590 alc262_check_volbit(cfg->hp_pins[0]);
11591 if (vbits == 1 || vbits == 2)
11592 pfx = "Master"; /* only one mixer is used */
11593 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11594 pfx = "Speaker";
11595 else
11596 pfx = "Front";
11597 vbits = 0;
11598 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11599 if (err < 0)
11600 return err;
11601 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11602 &vbits);
11603 if (err < 0)
11604 return err;
11605 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11606 &vbits);
11607 if (err < 0)
11608 return err;
f12ab1e0 11609 return 0;
df694daa
KY
11610}
11611
05f5f477 11612#define alc262_auto_create_input_ctls \
eaa9b3a7 11613 alc882_auto_create_input_ctls
df694daa
KY
11614
11615/*
11616 * generic initialization of ADC, input mixers and output mixers
11617 */
11618static struct hda_verb alc262_volume_init_verbs[] = {
11619 /*
11620 * Unmute ADC0-2 and set the default input to mic-in
11621 */
11622 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11624 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11626 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11628
cb53c626 11629 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11630 * mixer widget
f12ab1e0
TI
11631 * Note: PASD motherboards uses the Line In 2 as the input for
11632 * front panel mic (mic 2)
df694daa
KY
11633 */
11634 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11637 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11638 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11640
11641 /*
11642 * Set up output mixers (0x0c - 0x0f)
11643 */
11644 /* set vol=0 to output mixers */
11645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11647 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11648
df694daa
KY
11649 /* set up input amps for analog loopback */
11650 /* Amp Indices: DAC = 0, mixer = 1 */
11651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11653 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11654 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11656 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11657
11658 /* FIXME: use matrix-type input source selection */
11659 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11660 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11662 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11663 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11665 /* Input mixer2 */
11666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11667 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11670 /* Input mixer3 */
11671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11675
11676 { }
11677};
11678
9c7f852e
TI
11679static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11680 /*
11681 * Unmute ADC0-2 and set the default input to mic-in
11682 */
11683 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11686 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11687 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11688 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11689
cb53c626 11690 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11691 * mixer widget
f12ab1e0
TI
11692 * Note: PASD motherboards uses the Line In 2 as the input for
11693 * front panel mic (mic 2)
9c7f852e
TI
11694 */
11695 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11699 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11701 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11702 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11703
9c7f852e
TI
11704 /*
11705 * Set up output mixers (0x0c - 0x0e)
11706 */
11707 /* set vol=0 to output mixers */
11708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11710 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11711
11712 /* set up input amps for analog loopback */
11713 /* Amp Indices: DAC = 0, mixer = 1 */
11714 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11716 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11717 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11718 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11719 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11720
ce875f07 11721 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11724
11725 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11727
11728 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11729 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11730
11731 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11732 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11733 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11734 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11736
0e4835c1 11737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11740 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11741 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11742 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11743
11744
11745 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
11746 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11747 /* Input mixer1: only unmute Mic */
9c7f852e 11748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11749 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11750 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11751 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11753 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11757 /* Input mixer2 */
11758 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11759 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11760 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11761 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11767 /* Input mixer3 */
11768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 11777
ce875f07
TI
11778 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11779
9c7f852e
TI
11780 { }
11781};
11782
cd7509a4
KY
11783static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11784 /*
11785 * Unmute ADC0-2 and set the default input to mic-in
11786 */
11787 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11788 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11789 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11791 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11793
cb53c626 11794 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
11795 * mixer widget
11796 * Note: PASD motherboards uses the Line In 2 as the input for front
11797 * panel mic (mic 2)
11798 */
11799 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11800 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11801 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11802 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11803 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11804 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11805 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11806 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11807 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
11808 /*
11809 * Set up output mixers (0x0c - 0x0e)
11810 */
11811 /* set vol=0 to output mixers */
11812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11815
11816 /* set up input amps for analog loopback */
11817 /* Amp Indices: DAC = 0, mixer = 1 */
11818 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11820 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11821 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11822 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11823 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11824
11825
11826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11827 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11828 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11830 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11832 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11833
11834 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11835 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11836
11837 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11838 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11839
11840 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11841 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11842 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11843 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11844 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11845 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11846
11847 /* FIXME: use matrix-type input source selection */
11848 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11849 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11850 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11851 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11852 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11853 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11854 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11855 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11857 /* Input mixer2 */
11858 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11859 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11860 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11863 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11864 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11865 /* Input mixer3 */
11866 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11869 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11870 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11871 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11873
ce875f07
TI
11874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11875
cd7509a4
KY
11876 { }
11877};
11878
9f99a638
HM
11879static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11880
11881 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11882 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11883 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11884
11885 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11886 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11887 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11889
11890 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11891 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11892 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11893 {}
11894};
11895
11896
cb53c626
TI
11897#ifdef CONFIG_SND_HDA_POWER_SAVE
11898#define alc262_loopbacks alc880_loopbacks
11899#endif
11900
def319f9 11901/* pcm configuration: identical with ALC880 */
df694daa
KY
11902#define alc262_pcm_analog_playback alc880_pcm_analog_playback
11903#define alc262_pcm_analog_capture alc880_pcm_analog_capture
11904#define alc262_pcm_digital_playback alc880_pcm_digital_playback
11905#define alc262_pcm_digital_capture alc880_pcm_digital_capture
11906
11907/*
11908 * BIOS auto configuration
11909 */
11910static int alc262_parse_auto_config(struct hda_codec *codec)
11911{
11912 struct alc_spec *spec = codec->spec;
11913 int err;
11914 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11915
f12ab1e0
TI
11916 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11917 alc262_ignore);
11918 if (err < 0)
df694daa 11919 return err;
e64f14f4 11920 if (!spec->autocfg.line_outs) {
0852d7a6 11921 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
11922 spec->multiout.max_channels = 2;
11923 spec->no_analog = 1;
11924 goto dig_only;
11925 }
df694daa 11926 return 0; /* can't find valid BIOS pin config */
e64f14f4 11927 }
f12ab1e0
TI
11928 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11929 if (err < 0)
11930 return err;
05f5f477 11931 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 11932 if (err < 0)
df694daa
KY
11933 return err;
11934
11935 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11936
e64f14f4 11937 dig_only:
0852d7a6 11938 if (spec->autocfg.dig_outs) {
df694daa 11939 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 11940 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 11941 }
df694daa
KY
11942 if (spec->autocfg.dig_in_pin)
11943 spec->dig_in_nid = ALC262_DIGIN_NID;
11944
603c4019 11945 if (spec->kctls.list)
d88897ea 11946 add_mixer(spec, spec->kctls.list);
df694daa 11947
d88897ea 11948 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 11949 spec->num_mux_defs = 1;
61b9b9b1 11950 spec->input_mux = &spec->private_imux[0];
df694daa 11951
776e184e
TI
11952 err = alc_auto_add_mic_boost(codec);
11953 if (err < 0)
11954 return err;
11955
6227cdce 11956 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 11957
df694daa
KY
11958 return 1;
11959}
11960
11961#define alc262_auto_init_multi_out alc882_auto_init_multi_out
11962#define alc262_auto_init_hp_out alc882_auto_init_hp_out
11963#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 11964#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
11965
11966
11967/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 11968static void alc262_auto_init(struct hda_codec *codec)
df694daa 11969{
f6c7e546 11970 struct alc_spec *spec = codec->spec;
df694daa
KY
11971 alc262_auto_init_multi_out(codec);
11972 alc262_auto_init_hp_out(codec);
11973 alc262_auto_init_analog_input(codec);
f511b01c 11974 alc262_auto_init_input_src(codec);
f6c7e546 11975 if (spec->unsol_event)
7fb0d78f 11976 alc_inithook(codec);
df694daa
KY
11977}
11978
11979/*
11980 * configuration and preset
11981 */
f5fcc13c
TI
11982static const char *alc262_models[ALC262_MODEL_LAST] = {
11983 [ALC262_BASIC] = "basic",
11984 [ALC262_HIPPO] = "hippo",
11985 [ALC262_HIPPO_1] = "hippo_1",
11986 [ALC262_FUJITSU] = "fujitsu",
11987 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 11988 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 11989 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 11990 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 11991 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
11992 [ALC262_BENQ_T31] = "benq-t31",
11993 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 11994 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 11995 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 11996 [ALC262_ULTRA] = "ultra",
0e31daf7 11997 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 11998 [ALC262_NEC] = "nec",
ba340e82 11999 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12000 [ALC262_AUTO] = "auto",
12001};
12002
12003static struct snd_pci_quirk alc262_cfg_tbl[] = {
12004 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12005 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12006 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12007 ALC262_HP_BPC),
12008 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12009 ALC262_HP_BPC),
53eff7e1
TI
12010 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12011 ALC262_HP_BPC),
cd7509a4 12012 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12013 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12014 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12015 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12016 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12017 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12018 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12019 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12020 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12021 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12022 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12023 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12024 ALC262_HP_TC_T5735),
8c427226 12025 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12026 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12027 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12028 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12029 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12030 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12031 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12032 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12033#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12034 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12035 ALC262_SONY_ASSAMD),
c5b5165c 12036#endif
36ca6e13 12037 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12038 ALC262_TOSHIBA_RX1),
80ffe869 12039 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12040 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12041 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12042 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12043 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12044 ALC262_ULTRA),
3e420e78 12045 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12046 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12047 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12048 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12049 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12050 {}
12051};
12052
12053static struct alc_config_preset alc262_presets[] = {
12054 [ALC262_BASIC] = {
12055 .mixers = { alc262_base_mixer },
12056 .init_verbs = { alc262_init_verbs },
12057 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12058 .dac_nids = alc262_dac_nids,
12059 .hp_nid = 0x03,
12060 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12061 .channel_mode = alc262_modes,
a3bcba38 12062 .input_mux = &alc262_capture_source,
df694daa 12063 },
ccc656ce 12064 [ALC262_HIPPO] = {
42171c17 12065 .mixers = { alc262_hippo_mixer },
6732bd0d 12066 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12067 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12068 .dac_nids = alc262_dac_nids,
12069 .hp_nid = 0x03,
12070 .dig_out_nid = ALC262_DIGOUT_NID,
12071 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12072 .channel_mode = alc262_modes,
12073 .input_mux = &alc262_capture_source,
12074 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12075 .setup = alc262_hippo_setup,
12076 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12077 },
12078 [ALC262_HIPPO_1] = {
12079 .mixers = { alc262_hippo1_mixer },
12080 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12081 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12082 .dac_nids = alc262_dac_nids,
12083 .hp_nid = 0x02,
12084 .dig_out_nid = ALC262_DIGOUT_NID,
12085 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12086 .channel_mode = alc262_modes,
12087 .input_mux = &alc262_capture_source,
42171c17 12088 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12089 .setup = alc262_hippo1_setup,
12090 .init_hook = alc262_hippo_automute,
ccc656ce 12091 },
834be88d
TI
12092 [ALC262_FUJITSU] = {
12093 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12094 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12095 alc262_fujitsu_unsol_verbs },
834be88d
TI
12096 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12097 .dac_nids = alc262_dac_nids,
12098 .hp_nid = 0x03,
12099 .dig_out_nid = ALC262_DIGOUT_NID,
12100 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12101 .channel_mode = alc262_modes,
12102 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12103 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12104 .init_hook = alc262_fujitsu_init_hook,
834be88d 12105 },
9c7f852e
TI
12106 [ALC262_HP_BPC] = {
12107 .mixers = { alc262_HP_BPC_mixer },
12108 .init_verbs = { alc262_HP_BPC_init_verbs },
12109 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12110 .dac_nids = alc262_dac_nids,
12111 .hp_nid = 0x03,
12112 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12113 .channel_mode = alc262_modes,
12114 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12115 .unsol_event = alc262_hp_bpc_unsol_event,
12116 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12117 },
cd7509a4
KY
12118 [ALC262_HP_BPC_D7000_WF] = {
12119 .mixers = { alc262_HP_BPC_WildWest_mixer },
12120 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12121 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12122 .dac_nids = alc262_dac_nids,
12123 .hp_nid = 0x03,
12124 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12125 .channel_mode = alc262_modes,
accbe498 12126 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12127 .unsol_event = alc262_hp_wildwest_unsol_event,
12128 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12129 },
cd7509a4
KY
12130 [ALC262_HP_BPC_D7000_WL] = {
12131 .mixers = { alc262_HP_BPC_WildWest_mixer,
12132 alc262_HP_BPC_WildWest_option_mixer },
12133 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12134 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12135 .dac_nids = alc262_dac_nids,
12136 .hp_nid = 0x03,
12137 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12138 .channel_mode = alc262_modes,
accbe498 12139 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12140 .unsol_event = alc262_hp_wildwest_unsol_event,
12141 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12142 },
66d2a9d6
KY
12143 [ALC262_HP_TC_T5735] = {
12144 .mixers = { alc262_hp_t5735_mixer },
12145 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12146 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12147 .dac_nids = alc262_dac_nids,
12148 .hp_nid = 0x03,
12149 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12150 .channel_mode = alc262_modes,
12151 .input_mux = &alc262_capture_source,
dc99be47 12152 .unsol_event = alc_sku_unsol_event,
4f5d1706 12153 .setup = alc262_hp_t5735_setup,
dc99be47 12154 .init_hook = alc_inithook,
8c427226
KY
12155 },
12156 [ALC262_HP_RP5700] = {
12157 .mixers = { alc262_hp_rp5700_mixer },
12158 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12159 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12160 .dac_nids = alc262_dac_nids,
12161 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12162 .channel_mode = alc262_modes,
12163 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12164 },
304dcaac
TI
12165 [ALC262_BENQ_ED8] = {
12166 .mixers = { alc262_base_mixer },
12167 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12168 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12169 .dac_nids = alc262_dac_nids,
12170 .hp_nid = 0x03,
12171 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12172 .channel_mode = alc262_modes,
12173 .input_mux = &alc262_capture_source,
f12ab1e0 12174 },
272a527c
KY
12175 [ALC262_SONY_ASSAMD] = {
12176 .mixers = { alc262_sony_mixer },
12177 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12178 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12179 .dac_nids = alc262_dac_nids,
12180 .hp_nid = 0x02,
12181 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12182 .channel_mode = alc262_modes,
12183 .input_mux = &alc262_capture_source,
12184 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12185 .setup = alc262_hippo_setup,
12186 .init_hook = alc262_hippo_automute,
83c34218
KY
12187 },
12188 [ALC262_BENQ_T31] = {
12189 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12190 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12191 alc_hp15_unsol_verbs },
83c34218
KY
12192 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12193 .dac_nids = alc262_dac_nids,
12194 .hp_nid = 0x03,
12195 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12196 .channel_mode = alc262_modes,
12197 .input_mux = &alc262_capture_source,
12198 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12199 .setup = alc262_hippo_setup,
12200 .init_hook = alc262_hippo_automute,
ea1fb29a 12201 },
f651b50b 12202 [ALC262_ULTRA] = {
f9e336f6
TI
12203 .mixers = { alc262_ultra_mixer },
12204 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12205 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12206 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12207 .dac_nids = alc262_dac_nids,
f651b50b
TD
12208 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12209 .channel_mode = alc262_modes,
12210 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12211 .adc_nids = alc262_adc_nids, /* ADC0 */
12212 .capsrc_nids = alc262_capsrc_nids,
12213 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12214 .unsol_event = alc262_ultra_unsol_event,
12215 .init_hook = alc262_ultra_automute,
12216 },
0e31daf7
J
12217 [ALC262_LENOVO_3000] = {
12218 .mixers = { alc262_lenovo_3000_mixer },
12219 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12220 alc262_lenovo_3000_unsol_verbs,
12221 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12222 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12223 .dac_nids = alc262_dac_nids,
12224 .hp_nid = 0x03,
12225 .dig_out_nid = ALC262_DIGOUT_NID,
12226 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12227 .channel_mode = alc262_modes,
12228 .input_mux = &alc262_fujitsu_capture_source,
12229 .unsol_event = alc262_lenovo_3000_unsol_event,
12230 },
e8f9ae2a
PT
12231 [ALC262_NEC] = {
12232 .mixers = { alc262_nec_mixer },
12233 .init_verbs = { alc262_nec_verbs },
12234 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12235 .dac_nids = alc262_dac_nids,
12236 .hp_nid = 0x03,
12237 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12238 .channel_mode = alc262_modes,
12239 .input_mux = &alc262_capture_source,
12240 },
4e555fe5
KY
12241 [ALC262_TOSHIBA_S06] = {
12242 .mixers = { alc262_toshiba_s06_mixer },
12243 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12244 alc262_eapd_verbs },
12245 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12246 .capsrc_nids = alc262_dmic_capsrc_nids,
12247 .dac_nids = alc262_dac_nids,
12248 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12249 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12250 .dig_out_nid = ALC262_DIGOUT_NID,
12251 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12252 .channel_mode = alc262_modes,
4f5d1706
TI
12253 .unsol_event = alc_sku_unsol_event,
12254 .setup = alc262_toshiba_s06_setup,
12255 .init_hook = alc_inithook,
4e555fe5 12256 },
9f99a638
HM
12257 [ALC262_TOSHIBA_RX1] = {
12258 .mixers = { alc262_toshiba_rx1_mixer },
12259 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12260 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12261 .dac_nids = alc262_dac_nids,
12262 .hp_nid = 0x03,
12263 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12264 .channel_mode = alc262_modes,
12265 .input_mux = &alc262_capture_source,
12266 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12267 .setup = alc262_hippo_setup,
12268 .init_hook = alc262_hippo_automute,
9f99a638 12269 },
ba340e82
TV
12270 [ALC262_TYAN] = {
12271 .mixers = { alc262_tyan_mixer },
12272 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12273 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12274 .dac_nids = alc262_dac_nids,
12275 .hp_nid = 0x02,
12276 .dig_out_nid = ALC262_DIGOUT_NID,
12277 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12278 .channel_mode = alc262_modes,
12279 .input_mux = &alc262_capture_source,
a9fd4f3f 12280 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12281 .setup = alc262_tyan_setup,
12282 .init_hook = alc_automute_amp,
ba340e82 12283 },
df694daa
KY
12284};
12285
12286static int patch_alc262(struct hda_codec *codec)
12287{
12288 struct alc_spec *spec;
12289 int board_config;
12290 int err;
12291
dc041e0b 12292 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12293 if (spec == NULL)
12294 return -ENOMEM;
12295
12296 codec->spec = spec;
12297#if 0
f12ab1e0
TI
12298 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12299 * under-run
12300 */
df694daa
KY
12301 {
12302 int tmp;
12303 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12304 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12305 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12306 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12307 }
12308#endif
da00c244 12309 alc_auto_parse_customize_define(codec);
df694daa 12310
2c3bf9ab
TI
12311 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12312
f5fcc13c
TI
12313 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12314 alc262_models,
12315 alc262_cfg_tbl);
cd7509a4 12316
f5fcc13c 12317 if (board_config < 0) {
9a11f1aa
TI
12318 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12319 codec->chip_name);
df694daa
KY
12320 board_config = ALC262_AUTO;
12321 }
12322
12323 if (board_config == ALC262_AUTO) {
12324 /* automatic parse from the BIOS config */
12325 err = alc262_parse_auto_config(codec);
12326 if (err < 0) {
12327 alc_free(codec);
12328 return err;
f12ab1e0 12329 } else if (!err) {
9c7f852e
TI
12330 printk(KERN_INFO
12331 "hda_codec: Cannot set up configuration "
12332 "from BIOS. Using base mode...\n");
df694daa
KY
12333 board_config = ALC262_BASIC;
12334 }
12335 }
12336
07eba61d
TI
12337 if (!spec->no_analog) {
12338 err = snd_hda_attach_beep_device(codec, 0x1);
12339 if (err < 0) {
12340 alc_free(codec);
12341 return err;
12342 }
680cd536
KK
12343 }
12344
df694daa 12345 if (board_config != ALC262_AUTO)
e9c364c0 12346 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12347
df694daa
KY
12348 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12349 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12350
df694daa
KY
12351 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12352 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12353
f12ab1e0 12354 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12355 int i;
12356 /* check whether the digital-mic has to be supported */
12357 for (i = 0; i < spec->input_mux->num_items; i++) {
12358 if (spec->input_mux->items[i].index >= 9)
12359 break;
12360 }
12361 if (i < spec->input_mux->num_items) {
12362 /* use only ADC0 */
12363 spec->adc_nids = alc262_dmic_adc_nids;
12364 spec->num_adc_nids = 1;
12365 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12366 } else {
8c927b4a
TI
12367 /* all analog inputs */
12368 /* check whether NID 0x07 is valid */
12369 unsigned int wcap = get_wcaps(codec, 0x07);
12370
12371 /* get type */
a22d543a 12372 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12373 if (wcap != AC_WID_AUD_IN) {
12374 spec->adc_nids = alc262_adc_nids_alt;
12375 spec->num_adc_nids =
12376 ARRAY_SIZE(alc262_adc_nids_alt);
12377 spec->capsrc_nids = alc262_capsrc_nids_alt;
12378 } else {
12379 spec->adc_nids = alc262_adc_nids;
12380 spec->num_adc_nids =
12381 ARRAY_SIZE(alc262_adc_nids);
12382 spec->capsrc_nids = alc262_capsrc_nids;
12383 }
df694daa
KY
12384 }
12385 }
e64f14f4 12386 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12387 set_capture_mixer(codec);
da00c244 12388 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
07eba61d 12389 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12390
2134ea4f
TI
12391 spec->vmaster_nid = 0x0c;
12392
df694daa
KY
12393 codec->patch_ops = alc_patch_ops;
12394 if (board_config == ALC262_AUTO)
ae6b813a 12395 spec->init_hook = alc262_auto_init;
cb53c626
TI
12396#ifdef CONFIG_SND_HDA_POWER_SAVE
12397 if (!spec->loopback.amplist)
12398 spec->loopback.amplist = alc262_loopbacks;
12399#endif
ea1fb29a 12400
df694daa
KY
12401 return 0;
12402}
12403
a361d84b
KY
12404/*
12405 * ALC268 channel source setting (2 channel)
12406 */
12407#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12408#define alc268_modes alc260_modes
ea1fb29a 12409
a361d84b
KY
12410static hda_nid_t alc268_dac_nids[2] = {
12411 /* front, hp */
12412 0x02, 0x03
12413};
12414
12415static hda_nid_t alc268_adc_nids[2] = {
12416 /* ADC0-1 */
12417 0x08, 0x07
12418};
12419
12420static hda_nid_t alc268_adc_nids_alt[1] = {
12421 /* ADC0 */
12422 0x08
12423};
12424
e1406348
TI
12425static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12426
a361d84b
KY
12427static struct snd_kcontrol_new alc268_base_mixer[] = {
12428 /* output mixer control */
12429 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12430 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12431 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12432 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12433 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12434 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12435 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12436 { }
12437};
12438
42171c17
TI
12439static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12440 /* output mixer control */
12441 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12442 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12443 ALC262_HIPPO_MASTER_SWITCH,
12444 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12445 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12446 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12447 { }
12448};
12449
aef9d318
TI
12450/* bind Beep switches of both NID 0x0f and 0x10 */
12451static struct hda_bind_ctls alc268_bind_beep_sw = {
12452 .ops = &snd_hda_bind_sw,
12453 .values = {
12454 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12455 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12456 0
12457 },
12458};
12459
12460static struct snd_kcontrol_new alc268_beep_mixer[] = {
12461 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12462 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12463 { }
12464};
12465
d1a991a6
KY
12466static struct hda_verb alc268_eapd_verbs[] = {
12467 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12468 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12469 { }
12470};
12471
d273809e 12472/* Toshiba specific */
d273809e
TI
12473static struct hda_verb alc268_toshiba_verbs[] = {
12474 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12475 { } /* end */
12476};
12477
12478/* Acer specific */
889c4395 12479/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12480static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12481 .ops = &snd_hda_bind_vol,
12482 .values = {
12483 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12484 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12485 0
12486 },
12487};
12488
889c4395
TI
12489/* mute/unmute internal speaker according to the hp jack and mute state */
12490static void alc268_acer_automute(struct hda_codec *codec, int force)
12491{
12492 struct alc_spec *spec = codec->spec;
12493 unsigned int mute;
12494
12495 if (force || !spec->sense_updated) {
864f92be 12496 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12497 spec->sense_updated = 1;
12498 }
12499 if (spec->jack_present)
12500 mute = HDA_AMP_MUTE; /* mute internal speaker */
12501 else /* unmute internal speaker if necessary */
12502 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12503 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12504 HDA_AMP_MUTE, mute);
12505}
12506
12507
12508/* bind hp and internal speaker mute (with plug check) */
12509static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12510 struct snd_ctl_elem_value *ucontrol)
12511{
12512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12513 long *valp = ucontrol->value.integer.value;
12514 int change;
12515
8de56b7d 12516 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12517 if (change)
12518 alc268_acer_automute(codec, 0);
12519 return change;
12520}
d273809e 12521
8ef355da
KY
12522static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12523 /* output mixer control */
12524 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12525 {
12526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12527 .name = "Master Playback Switch",
5e26dfd0 12528 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12529 .info = snd_hda_mixer_amp_switch_info,
12530 .get = snd_hda_mixer_amp_switch_get,
12531 .put = alc268_acer_master_sw_put,
12532 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12533 },
12534 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12535 { }
12536};
12537
d273809e
TI
12538static struct snd_kcontrol_new alc268_acer_mixer[] = {
12539 /* output mixer control */
12540 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12541 {
12542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12543 .name = "Master Playback Switch",
5e26dfd0 12544 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12545 .info = snd_hda_mixer_amp_switch_info,
12546 .get = snd_hda_mixer_amp_switch_get,
12547 .put = alc268_acer_master_sw_put,
12548 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12549 },
33bf17ab
TI
12550 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12551 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12552 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12553 { }
12554};
12555
c238b4f4
TI
12556static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12557 /* output mixer control */
12558 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12559 {
12560 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12561 .name = "Master Playback Switch",
5e26dfd0 12562 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12563 .info = snd_hda_mixer_amp_switch_info,
12564 .get = snd_hda_mixer_amp_switch_get,
12565 .put = alc268_acer_master_sw_put,
12566 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12567 },
12568 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12569 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12570 { }
12571};
12572
8ef355da
KY
12573static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12574 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12578 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12580 { }
12581};
12582
d273809e 12583static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12584 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12585 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12586 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12588 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12590 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12591 { }
12592};
12593
12594/* unsolicited event for HP jack sensing */
42171c17 12595#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12596#define alc268_toshiba_setup alc262_hippo_setup
12597#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12598
12599static void alc268_acer_unsol_event(struct hda_codec *codec,
12600 unsigned int res)
12601{
889c4395 12602 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12603 return;
12604 alc268_acer_automute(codec, 1);
12605}
12606
889c4395
TI
12607static void alc268_acer_init_hook(struct hda_codec *codec)
12608{
12609 alc268_acer_automute(codec, 1);
12610}
12611
8ef355da
KY
12612/* toggle speaker-output according to the hp-jack state */
12613static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12614{
12615 unsigned int present;
12616 unsigned char bits;
12617
864f92be 12618 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12619 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12620 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12621 HDA_AMP_MUTE, bits);
8ef355da 12622 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12623 HDA_AMP_MUTE, bits);
8ef355da
KY
12624}
12625
8ef355da
KY
12626static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12627 unsigned int res)
12628{
4f5d1706
TI
12629 switch (res >> 26) {
12630 case ALC880_HP_EVENT:
8ef355da 12631 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12632 break;
12633 case ALC880_MIC_EVENT:
12634 alc_mic_automute(codec);
12635 break;
12636 }
12637}
12638
12639static void alc268_acer_lc_setup(struct hda_codec *codec)
12640{
12641 struct alc_spec *spec = codec->spec;
12642 spec->ext_mic.pin = 0x18;
12643 spec->ext_mic.mux_idx = 0;
12644 spec->int_mic.pin = 0x12;
12645 spec->int_mic.mux_idx = 6;
12646 spec->auto_mic = 1;
8ef355da
KY
12647}
12648
12649static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12650{
12651 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12652 alc_mic_automute(codec);
8ef355da
KY
12653}
12654
3866f0b0
TI
12655static struct snd_kcontrol_new alc268_dell_mixer[] = {
12656 /* output mixer control */
12657 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12658 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12659 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12660 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12661 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12662 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12663 { }
12664};
12665
12666static struct hda_verb alc268_dell_verbs[] = {
12667 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12668 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12669 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12670 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12671 { }
12672};
12673
12674/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12675static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12676{
a9fd4f3f 12677 struct alc_spec *spec = codec->spec;
3866f0b0 12678
a9fd4f3f
TI
12679 spec->autocfg.hp_pins[0] = 0x15;
12680 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12681 spec->ext_mic.pin = 0x18;
12682 spec->ext_mic.mux_idx = 0;
12683 spec->int_mic.pin = 0x19;
12684 spec->int_mic.mux_idx = 1;
12685 spec->auto_mic = 1;
3866f0b0
TI
12686}
12687
eb5a6621
HRK
12688static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12689 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12690 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12691 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12692 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12693 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12694 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12695 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12697 { }
12698};
12699
12700static struct hda_verb alc267_quanta_il1_verbs[] = {
12701 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12702 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12703 { }
12704};
12705
4f5d1706 12706static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12707{
a9fd4f3f 12708 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12709 spec->autocfg.hp_pins[0] = 0x15;
12710 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12711 spec->ext_mic.pin = 0x18;
12712 spec->ext_mic.mux_idx = 0;
12713 spec->int_mic.pin = 0x19;
12714 spec->int_mic.mux_idx = 1;
12715 spec->auto_mic = 1;
eb5a6621
HRK
12716}
12717
a361d84b
KY
12718/*
12719 * generic initialization of ADC, input mixers and output mixers
12720 */
12721static struct hda_verb alc268_base_init_verbs[] = {
12722 /* Unmute DAC0-1 and set vol = 0 */
12723 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12724 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12725
12726 /*
12727 * Set up output mixers (0x0c - 0x0e)
12728 */
12729 /* set vol=0 to output mixers */
12730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12731 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12732
12733 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12734 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735
12736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12737 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12738 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12739 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12740 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12742 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12743 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12744
12745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12747 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12750
12751 /* set PCBEEP vol = 0, mute connections */
12752 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12753 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12754 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12755
a9b3aa8a 12756 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12757
a9b3aa8a
JZ
12758 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12759 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12760 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 12762
a361d84b
KY
12763 { }
12764};
12765
12766/*
12767 * generic initialization of ADC, input mixers and output mixers
12768 */
12769static struct hda_verb alc268_volume_init_verbs[] = {
12770 /* set output DAC */
4cfb91c6
TI
12771 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12772 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12773
12774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12775 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12778 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12779
a361d84b 12780 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12781 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12782 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12783
12784 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12785 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12786
aef9d318
TI
12787 /* set PCBEEP vol = 0, mute connections */
12788 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12789 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12790 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
12791
12792 { }
12793};
12794
fdbc6626
TI
12795static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12796 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12797 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12798 { } /* end */
12799};
12800
a361d84b
KY
12801static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12802 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12803 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 12804 _DEFINE_CAPSRC(1),
a361d84b
KY
12805 { } /* end */
12806};
12807
12808static struct snd_kcontrol_new alc268_capture_mixer[] = {
12809 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12810 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12811 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12812 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 12813 _DEFINE_CAPSRC(2),
a361d84b
KY
12814 { } /* end */
12815};
12816
12817static struct hda_input_mux alc268_capture_source = {
12818 .num_items = 4,
12819 .items = {
12820 { "Mic", 0x0 },
12821 { "Front Mic", 0x1 },
12822 { "Line", 0x2 },
12823 { "CD", 0x3 },
12824 },
12825};
12826
0ccb541c 12827static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
12828 .num_items = 3,
12829 .items = {
12830 { "Mic", 0x0 },
12831 { "Internal Mic", 0x1 },
12832 { "Line", 0x2 },
12833 },
12834};
12835
12836static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
12837 .num_items = 3,
12838 .items = {
12839 { "Mic", 0x0 },
12840 { "Internal Mic", 0x6 },
12841 { "Line", 0x2 },
12842 },
12843};
12844
86c53bd2
JW
12845#ifdef CONFIG_SND_DEBUG
12846static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
12847 /* Volume widgets */
12848 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12849 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12850 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12851 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12852 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12853 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12854 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12855 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12856 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12857 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12858 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12859 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12860 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
12861 /* The below appears problematic on some hardwares */
12862 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
12863 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12864 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12865 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12866 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12867
12868 /* Modes for retasking pin widgets */
12869 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12870 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12871 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12872 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12873
12874 /* Controls for GPIO pins, assuming they are configured as outputs */
12875 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12876 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12877 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12878 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12879
12880 /* Switches to allow the digital SPDIF output pin to be enabled.
12881 * The ALC268 does not have an SPDIF input.
12882 */
12883 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12884
12885 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12886 * this output to turn on an external amplifier.
12887 */
12888 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12889 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12890
12891 { } /* end */
12892};
12893#endif
12894
a361d84b
KY
12895/* create input playback/capture controls for the given pin */
12896static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12897 const char *ctlname, int idx)
12898{
3f3b7c1a 12899 hda_nid_t dac;
a361d84b
KY
12900 int err;
12901
3f3b7c1a
TI
12902 switch (nid) {
12903 case 0x14:
12904 case 0x16:
12905 dac = 0x02;
12906 break;
12907 case 0x15:
12908 dac = 0x03;
12909 break;
12910 default:
12911 return 0;
12912 }
12913 if (spec->multiout.dac_nids[0] != dac &&
12914 spec->multiout.dac_nids[1] != dac) {
0afe5f89 12915 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 12916 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
12917 HDA_OUTPUT));
12918 if (err < 0)
12919 return err;
3f3b7c1a
TI
12920 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12921 }
12922
3f3b7c1a 12923 if (nid != 0x16)
0afe5f89 12924 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 12925 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 12926 else /* mono */
0afe5f89 12927 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 12928 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
12929 if (err < 0)
12930 return err;
12931 return 0;
12932}
12933
12934/* add playback controls from the parsed DAC table */
12935static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12936 const struct auto_pin_cfg *cfg)
12937{
12938 hda_nid_t nid;
12939 int err;
12940
a361d84b 12941 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
12942
12943 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
12944 if (nid) {
12945 const char *name;
12946 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12947 name = "Speaker";
12948 else
12949 name = "Front";
12950 err = alc268_new_analog_output(spec, nid, name, 0);
12951 if (err < 0)
12952 return err;
12953 }
a361d84b
KY
12954
12955 nid = cfg->speaker_pins[0];
12956 if (nid == 0x1d) {
0afe5f89 12957 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
12958 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12959 if (err < 0)
12960 return err;
3f3b7c1a
TI
12961 } else {
12962 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12963 if (err < 0)
12964 return err;
a361d84b
KY
12965 }
12966 nid = cfg->hp_pins[0];
3f3b7c1a
TI
12967 if (nid) {
12968 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12969 if (err < 0)
12970 return err;
12971 }
a361d84b
KY
12972
12973 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12974 if (nid == 0x16) {
0afe5f89 12975 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 12976 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
12977 if (err < 0)
12978 return err;
12979 }
ea1fb29a 12980 return 0;
a361d84b
KY
12981}
12982
12983/* create playback/capture controls for input pins */
05f5f477 12984static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
12985 const struct auto_pin_cfg *cfg)
12986{
05f5f477 12987 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
12988}
12989
e9af4f36
TI
12990static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12991 hda_nid_t nid, int pin_type)
12992{
12993 int idx;
12994
12995 alc_set_pin_output(codec, nid, pin_type);
12996 if (nid == 0x14 || nid == 0x16)
12997 idx = 0;
12998 else
12999 idx = 1;
13000 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13001}
13002
13003static void alc268_auto_init_multi_out(struct hda_codec *codec)
13004{
13005 struct alc_spec *spec = codec->spec;
13006 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13007 if (nid) {
13008 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13009 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13010 }
13011}
13012
13013static void alc268_auto_init_hp_out(struct hda_codec *codec)
13014{
13015 struct alc_spec *spec = codec->spec;
13016 hda_nid_t pin;
13017
13018 pin = spec->autocfg.hp_pins[0];
13019 if (pin)
13020 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13021 pin = spec->autocfg.speaker_pins[0];
13022 if (pin)
13023 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13024}
13025
a361d84b
KY
13026static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13027{
13028 struct alc_spec *spec = codec->spec;
13029 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13030 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13031 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13032 unsigned int dac_vol1, dac_vol2;
13033
e9af4f36 13034 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13035 snd_hda_codec_write(codec, speaker_nid, 0,
13036 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13037 /* mute mixer inputs from 0x1d */
a361d84b
KY
13038 snd_hda_codec_write(codec, 0x0f, 0,
13039 AC_VERB_SET_AMP_GAIN_MUTE,
13040 AMP_IN_UNMUTE(1));
13041 snd_hda_codec_write(codec, 0x10, 0,
13042 AC_VERB_SET_AMP_GAIN_MUTE,
13043 AMP_IN_UNMUTE(1));
13044 } else {
e9af4f36 13045 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13046 snd_hda_codec_write(codec, 0x0f, 0,
13047 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13048 snd_hda_codec_write(codec, 0x10, 0,
13049 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13050 }
13051
13052 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13053 if (line_nid == 0x14)
a361d84b
KY
13054 dac_vol2 = AMP_OUT_ZERO;
13055 else if (line_nid == 0x15)
13056 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13057 if (hp_nid == 0x14)
a361d84b
KY
13058 dac_vol2 = AMP_OUT_ZERO;
13059 else if (hp_nid == 0x15)
13060 dac_vol1 = AMP_OUT_ZERO;
13061 if (line_nid != 0x16 || hp_nid != 0x16 ||
13062 spec->autocfg.line_out_pins[1] != 0x16 ||
13063 spec->autocfg.line_out_pins[2] != 0x16)
13064 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13065
13066 snd_hda_codec_write(codec, 0x02, 0,
13067 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13068 snd_hda_codec_write(codec, 0x03, 0,
13069 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13070}
13071
def319f9 13072/* pcm configuration: identical with ALC880 */
a361d84b
KY
13073#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13074#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13075#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13076#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13077
13078/*
13079 * BIOS auto configuration
13080 */
13081static int alc268_parse_auto_config(struct hda_codec *codec)
13082{
13083 struct alc_spec *spec = codec->spec;
13084 int err;
13085 static hda_nid_t alc268_ignore[] = { 0 };
13086
13087 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13088 alc268_ignore);
13089 if (err < 0)
13090 return err;
7e0e44d4
TI
13091 if (!spec->autocfg.line_outs) {
13092 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13093 spec->multiout.max_channels = 2;
13094 spec->no_analog = 1;
13095 goto dig_only;
13096 }
a361d84b 13097 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13098 }
a361d84b
KY
13099 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13100 if (err < 0)
13101 return err;
05f5f477 13102 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13103 if (err < 0)
13104 return err;
13105
13106 spec->multiout.max_channels = 2;
13107
7e0e44d4 13108 dig_only:
a361d84b 13109 /* digital only support output */
7e0e44d4 13110 if (spec->autocfg.dig_outs) {
a361d84b 13111 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
13112 spec->dig_out_type = spec->autocfg.dig_out_type[0];
13113 }
603c4019 13114 if (spec->kctls.list)
d88897ea 13115 add_mixer(spec, spec->kctls.list);
a361d84b 13116
892981ff 13117 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13118 add_mixer(spec, alc268_beep_mixer);
aef9d318 13119
d88897ea 13120 add_verb(spec, alc268_volume_init_verbs);
5908589f 13121 spec->num_mux_defs = 2;
61b9b9b1 13122 spec->input_mux = &spec->private_imux[0];
a361d84b 13123
776e184e
TI
13124 err = alc_auto_add_mic_boost(codec);
13125 if (err < 0)
13126 return err;
13127
6227cdce 13128 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13129
a361d84b
KY
13130 return 1;
13131}
13132
a361d84b
KY
13133#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13134
13135/* init callback for auto-configuration model -- overriding the default init */
13136static void alc268_auto_init(struct hda_codec *codec)
13137{
f6c7e546 13138 struct alc_spec *spec = codec->spec;
a361d84b
KY
13139 alc268_auto_init_multi_out(codec);
13140 alc268_auto_init_hp_out(codec);
13141 alc268_auto_init_mono_speaker_out(codec);
13142 alc268_auto_init_analog_input(codec);
f6c7e546 13143 if (spec->unsol_event)
7fb0d78f 13144 alc_inithook(codec);
a361d84b
KY
13145}
13146
13147/*
13148 * configuration and preset
13149 */
13150static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13151 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13152 [ALC268_3ST] = "3stack",
983f8ae4 13153 [ALC268_TOSHIBA] = "toshiba",
d273809e 13154 [ALC268_ACER] = "acer",
c238b4f4 13155 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13156 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13157 [ALC268_DELL] = "dell",
f12462c5 13158 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13159#ifdef CONFIG_SND_DEBUG
13160 [ALC268_TEST] = "test",
13161#endif
a361d84b
KY
13162 [ALC268_AUTO] = "auto",
13163};
13164
13165static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13166 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13167 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13168 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13169 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13170 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13171 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13172 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13173 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13174 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13175 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13176 /* almost compatible with toshiba but with optional digital outs;
13177 * auto-probing seems working fine
13178 */
8871e5b9 13179 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13180 ALC268_AUTO),
a361d84b 13181 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13182 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13183 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13184 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13185 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13186 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13187 {}
13188};
13189
3abf2f36
TI
13190/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13191static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13192 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13193 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13194 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13195 ALC268_TOSHIBA),
13196 {}
13197};
13198
a361d84b 13199static struct alc_config_preset alc268_presets[] = {
eb5a6621 13200 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13201 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13202 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13203 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13204 alc267_quanta_il1_verbs },
13205 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13206 .dac_nids = alc268_dac_nids,
13207 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13208 .adc_nids = alc268_adc_nids_alt,
13209 .hp_nid = 0x03,
13210 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13211 .channel_mode = alc268_modes,
4f5d1706
TI
13212 .unsol_event = alc_sku_unsol_event,
13213 .setup = alc267_quanta_il1_setup,
13214 .init_hook = alc_inithook,
eb5a6621 13215 },
a361d84b 13216 [ALC268_3ST] = {
aef9d318
TI
13217 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13218 alc268_beep_mixer },
a361d84b
KY
13219 .init_verbs = { alc268_base_init_verbs },
13220 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13221 .dac_nids = alc268_dac_nids,
13222 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13223 .adc_nids = alc268_adc_nids_alt,
e1406348 13224 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13225 .hp_nid = 0x03,
13226 .dig_out_nid = ALC268_DIGOUT_NID,
13227 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13228 .channel_mode = alc268_modes,
13229 .input_mux = &alc268_capture_source,
13230 },
d1a991a6 13231 [ALC268_TOSHIBA] = {
42171c17 13232 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13233 alc268_beep_mixer },
d273809e
TI
13234 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13235 alc268_toshiba_verbs },
d1a991a6
KY
13236 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13237 .dac_nids = alc268_dac_nids,
13238 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13239 .adc_nids = alc268_adc_nids_alt,
e1406348 13240 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13241 .hp_nid = 0x03,
13242 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13243 .channel_mode = alc268_modes,
13244 .input_mux = &alc268_capture_source,
d273809e 13245 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13246 .setup = alc268_toshiba_setup,
13247 .init_hook = alc268_toshiba_automute,
d273809e
TI
13248 },
13249 [ALC268_ACER] = {
432fd133 13250 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13251 alc268_beep_mixer },
d273809e
TI
13252 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13253 alc268_acer_verbs },
13254 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13255 .dac_nids = alc268_dac_nids,
13256 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13257 .adc_nids = alc268_adc_nids_alt,
e1406348 13258 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13259 .hp_nid = 0x02,
13260 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13261 .channel_mode = alc268_modes,
0ccb541c 13262 .input_mux = &alc268_acer_capture_source,
d273809e 13263 .unsol_event = alc268_acer_unsol_event,
889c4395 13264 .init_hook = alc268_acer_init_hook,
d1a991a6 13265 },
c238b4f4
TI
13266 [ALC268_ACER_DMIC] = {
13267 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13268 alc268_beep_mixer },
13269 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13270 alc268_acer_verbs },
13271 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13272 .dac_nids = alc268_dac_nids,
13273 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13274 .adc_nids = alc268_adc_nids_alt,
13275 .capsrc_nids = alc268_capsrc_nids,
13276 .hp_nid = 0x02,
13277 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13278 .channel_mode = alc268_modes,
13279 .input_mux = &alc268_acer_dmic_capture_source,
13280 .unsol_event = alc268_acer_unsol_event,
13281 .init_hook = alc268_acer_init_hook,
13282 },
8ef355da
KY
13283 [ALC268_ACER_ASPIRE_ONE] = {
13284 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13285 alc268_beep_mixer,
fdbc6626 13286 alc268_capture_nosrc_mixer },
8ef355da
KY
13287 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13288 alc268_acer_aspire_one_verbs },
13289 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13290 .dac_nids = alc268_dac_nids,
13291 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13292 .adc_nids = alc268_adc_nids_alt,
13293 .capsrc_nids = alc268_capsrc_nids,
13294 .hp_nid = 0x03,
13295 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13296 .channel_mode = alc268_modes,
8ef355da 13297 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13298 .setup = alc268_acer_lc_setup,
8ef355da
KY
13299 .init_hook = alc268_acer_lc_init_hook,
13300 },
3866f0b0 13301 [ALC268_DELL] = {
fdbc6626
TI
13302 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13303 alc268_capture_nosrc_mixer },
3866f0b0
TI
13304 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13305 alc268_dell_verbs },
13306 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13307 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13308 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13309 .adc_nids = alc268_adc_nids_alt,
13310 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13311 .hp_nid = 0x02,
13312 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13313 .channel_mode = alc268_modes,
a9fd4f3f 13314 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13315 .setup = alc268_dell_setup,
13316 .init_hook = alc_inithook,
3866f0b0 13317 },
f12462c5 13318 [ALC268_ZEPTO] = {
aef9d318
TI
13319 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13320 alc268_beep_mixer },
f12462c5
MT
13321 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13322 alc268_toshiba_verbs },
13323 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13324 .dac_nids = alc268_dac_nids,
13325 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13326 .adc_nids = alc268_adc_nids_alt,
e1406348 13327 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13328 .hp_nid = 0x03,
13329 .dig_out_nid = ALC268_DIGOUT_NID,
13330 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13331 .channel_mode = alc268_modes,
13332 .input_mux = &alc268_capture_source,
4f5d1706
TI
13333 .setup = alc268_toshiba_setup,
13334 .init_hook = alc268_toshiba_automute,
f12462c5 13335 },
86c53bd2
JW
13336#ifdef CONFIG_SND_DEBUG
13337 [ALC268_TEST] = {
13338 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13339 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13340 alc268_volume_init_verbs },
13341 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13342 .dac_nids = alc268_dac_nids,
13343 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13344 .adc_nids = alc268_adc_nids_alt,
e1406348 13345 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13346 .hp_nid = 0x03,
13347 .dig_out_nid = ALC268_DIGOUT_NID,
13348 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13349 .channel_mode = alc268_modes,
13350 .input_mux = &alc268_capture_source,
13351 },
13352#endif
a361d84b
KY
13353};
13354
13355static int patch_alc268(struct hda_codec *codec)
13356{
13357 struct alc_spec *spec;
13358 int board_config;
22971e3a 13359 int i, has_beep, err;
a361d84b 13360
ef86f581 13361 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13362 if (spec == NULL)
13363 return -ENOMEM;
13364
13365 codec->spec = spec;
13366
13367 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13368 alc268_models,
13369 alc268_cfg_tbl);
13370
3abf2f36
TI
13371 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13372 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13373 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13374
a361d84b 13375 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13376 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13377 codec->chip_name);
a361d84b
KY
13378 board_config = ALC268_AUTO;
13379 }
13380
13381 if (board_config == ALC268_AUTO) {
13382 /* automatic parse from the BIOS config */
13383 err = alc268_parse_auto_config(codec);
13384 if (err < 0) {
13385 alc_free(codec);
13386 return err;
13387 } else if (!err) {
13388 printk(KERN_INFO
13389 "hda_codec: Cannot set up configuration "
13390 "from BIOS. Using base mode...\n");
13391 board_config = ALC268_3ST;
13392 }
13393 }
13394
13395 if (board_config != ALC268_AUTO)
e9c364c0 13396 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13397
a361d84b
KY
13398 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13399 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13400 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13401
a361d84b
KY
13402 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13403
22971e3a
TI
13404 has_beep = 0;
13405 for (i = 0; i < spec->num_mixers; i++) {
13406 if (spec->mixers[i] == alc268_beep_mixer) {
13407 has_beep = 1;
13408 break;
13409 }
13410 }
13411
13412 if (has_beep) {
13413 err = snd_hda_attach_beep_device(codec, 0x1);
13414 if (err < 0) {
13415 alc_free(codec);
13416 return err;
13417 }
13418 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13419 /* override the amp caps for beep generator */
13420 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13421 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13422 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13423 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13424 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13425 }
aef9d318 13426
7e0e44d4 13427 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13428 /* check whether NID 0x07 is valid */
13429 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13430 int i;
3866f0b0 13431
defb5ab2 13432 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13433 /* get type */
a22d543a 13434 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13435 if (spec->auto_mic ||
13436 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13437 spec->adc_nids = alc268_adc_nids_alt;
13438 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13439 if (spec->auto_mic)
13440 fixup_automic_adc(codec);
fdbc6626
TI
13441 if (spec->auto_mic || spec->input_mux->num_items == 1)
13442 add_mixer(spec, alc268_capture_nosrc_mixer);
13443 else
13444 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13445 } else {
13446 spec->adc_nids = alc268_adc_nids;
13447 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13448 add_mixer(spec, alc268_capture_mixer);
a361d84b 13449 }
85860c06
TI
13450 /* set default input source */
13451 for (i = 0; i < spec->num_adc_nids; i++)
13452 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13453 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13454 i < spec->num_mux_defs ?
13455 spec->input_mux[i].items[0].index :
85860c06 13456 spec->input_mux->items[0].index);
a361d84b 13457 }
2134ea4f
TI
13458
13459 spec->vmaster_nid = 0x02;
13460
a361d84b
KY
13461 codec->patch_ops = alc_patch_ops;
13462 if (board_config == ALC268_AUTO)
13463 spec->init_hook = alc268_auto_init;
ea1fb29a 13464
a361d84b
KY
13465 return 0;
13466}
13467
f6a92248
KY
13468/*
13469 * ALC269 channel source setting (2 channel)
13470 */
13471#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13472
13473#define alc269_dac_nids alc260_dac_nids
13474
13475static hda_nid_t alc269_adc_nids[1] = {
13476 /* ADC1 */
f53281e6
KY
13477 0x08,
13478};
13479
e01bf509
TI
13480static hda_nid_t alc269_capsrc_nids[1] = {
13481 0x23,
13482};
13483
84898e87
KY
13484static hda_nid_t alc269vb_adc_nids[1] = {
13485 /* ADC1 */
13486 0x09,
13487};
13488
13489static hda_nid_t alc269vb_capsrc_nids[1] = {
13490 0x22,
13491};
13492
6694635d
TI
13493static hda_nid_t alc269_adc_candidates[] = {
13494 0x08, 0x09, 0x07,
13495};
e01bf509 13496
f6a92248
KY
13497#define alc269_modes alc260_modes
13498#define alc269_capture_source alc880_lg_lw_capture_source
13499
13500static struct snd_kcontrol_new alc269_base_mixer[] = {
13501 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13502 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13506 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13507 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13508 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13509 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13510 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13511 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13512 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13513 { } /* end */
13514};
13515
60db6b53
KY
13516static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13517 /* output mixer control */
13518 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13519 {
13520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13521 .name = "Master Playback Switch",
5e26dfd0 13522 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13523 .info = snd_hda_mixer_amp_switch_info,
13524 .get = snd_hda_mixer_amp_switch_get,
13525 .put = alc268_acer_master_sw_put,
13526 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13527 },
13528 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13529 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13530 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13531 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13532 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13533 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13534 { }
13535};
13536
64154835
TV
13537static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13538 /* output mixer control */
13539 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13540 {
13541 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13542 .name = "Master Playback Switch",
5e26dfd0 13543 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13544 .info = snd_hda_mixer_amp_switch_info,
13545 .get = snd_hda_mixer_amp_switch_get,
13546 .put = alc268_acer_master_sw_put,
13547 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13548 },
13549 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13550 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13551 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13552 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13553 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13554 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13555 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13556 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13557 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13558 { }
13559};
13560
84898e87 13561static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13562 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13563 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13564 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13566 { } /* end */
13567};
13568
84898e87
KY
13569static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13570 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13571 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13574 { } /* end */
13575};
13576
f53281e6 13577/* capture mixer elements */
84898e87
KY
13578static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13579 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13580 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13581 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13582 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13583 { } /* end */
13584};
13585
13586static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13587 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13588 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13590 { } /* end */
13591};
13592
84898e87
KY
13593static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13594 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13595 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13597 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13598 { } /* end */
13599};
13600
13601static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13602 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13603 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13605 { } /* end */
13606};
13607
26f5df26 13608/* FSC amilo */
84898e87 13609#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13610
60db6b53
KY
13611static struct hda_verb alc269_quanta_fl1_verbs[] = {
13612 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13613 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13614 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13615 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13616 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13617 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13618 { }
13619};
f6a92248 13620
64154835
TV
13621static struct hda_verb alc269_lifebook_verbs[] = {
13622 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13623 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13624 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13626 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13627 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13629 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13630 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13631 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13632 { }
13633};
13634
60db6b53
KY
13635/* toggle speaker-output according to the hp-jack state */
13636static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13637{
13638 unsigned int present;
13639 unsigned char bits;
f6a92248 13640
864f92be 13641 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13642 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13643 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13644 HDA_AMP_MUTE, bits);
60db6b53 13645 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13646 HDA_AMP_MUTE, bits);
f6a92248 13647
60db6b53
KY
13648 snd_hda_codec_write(codec, 0x20, 0,
13649 AC_VERB_SET_COEF_INDEX, 0x0c);
13650 snd_hda_codec_write(codec, 0x20, 0,
13651 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13652
60db6b53
KY
13653 snd_hda_codec_write(codec, 0x20, 0,
13654 AC_VERB_SET_COEF_INDEX, 0x0c);
13655 snd_hda_codec_write(codec, 0x20, 0,
13656 AC_VERB_SET_PROC_COEF, 0x480);
13657}
f6a92248 13658
64154835
TV
13659/* toggle speaker-output according to the hp-jacks state */
13660static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13661{
13662 unsigned int present;
13663 unsigned char bits;
13664
13665 /* Check laptop headphone socket */
864f92be 13666 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13667
13668 /* Check port replicator headphone socket */
864f92be 13669 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13670
5dbd5ec6 13671 bits = present ? HDA_AMP_MUTE : 0;
64154835 13672 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13673 HDA_AMP_MUTE, bits);
64154835 13674 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13675 HDA_AMP_MUTE, bits);
64154835
TV
13676
13677 snd_hda_codec_write(codec, 0x20, 0,
13678 AC_VERB_SET_COEF_INDEX, 0x0c);
13679 snd_hda_codec_write(codec, 0x20, 0,
13680 AC_VERB_SET_PROC_COEF, 0x680);
13681
13682 snd_hda_codec_write(codec, 0x20, 0,
13683 AC_VERB_SET_COEF_INDEX, 0x0c);
13684 snd_hda_codec_write(codec, 0x20, 0,
13685 AC_VERB_SET_PROC_COEF, 0x480);
13686}
13687
64154835
TV
13688static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13689{
13690 unsigned int present_laptop;
13691 unsigned int present_dock;
13692
864f92be
WF
13693 present_laptop = snd_hda_jack_detect(codec, 0x18);
13694 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13695
13696 /* Laptop mic port overrides dock mic port, design decision */
13697 if (present_dock)
13698 snd_hda_codec_write(codec, 0x23, 0,
13699 AC_VERB_SET_CONNECT_SEL, 0x3);
13700 if (present_laptop)
13701 snd_hda_codec_write(codec, 0x23, 0,
13702 AC_VERB_SET_CONNECT_SEL, 0x0);
13703 if (!present_dock && !present_laptop)
13704 snd_hda_codec_write(codec, 0x23, 0,
13705 AC_VERB_SET_CONNECT_SEL, 0x1);
13706}
13707
60db6b53
KY
13708static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13709 unsigned int res)
13710{
4f5d1706
TI
13711 switch (res >> 26) {
13712 case ALC880_HP_EVENT:
60db6b53 13713 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13714 break;
13715 case ALC880_MIC_EVENT:
13716 alc_mic_automute(codec);
13717 break;
13718 }
60db6b53 13719}
f6a92248 13720
64154835
TV
13721static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13722 unsigned int res)
13723{
13724 if ((res >> 26) == ALC880_HP_EVENT)
13725 alc269_lifebook_speaker_automute(codec);
13726 if ((res >> 26) == ALC880_MIC_EVENT)
13727 alc269_lifebook_mic_autoswitch(codec);
13728}
13729
4f5d1706
TI
13730static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13731{
13732 struct alc_spec *spec = codec->spec;
20645d70
TI
13733 spec->autocfg.hp_pins[0] = 0x15;
13734 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13735 spec->ext_mic.pin = 0x18;
13736 spec->ext_mic.mux_idx = 0;
13737 spec->int_mic.pin = 0x19;
13738 spec->int_mic.mux_idx = 1;
13739 spec->auto_mic = 1;
13740}
13741
60db6b53
KY
13742static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13743{
13744 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13745 alc_mic_automute(codec);
60db6b53 13746}
f6a92248 13747
64154835
TV
13748static void alc269_lifebook_init_hook(struct hda_codec *codec)
13749{
13750 alc269_lifebook_speaker_automute(codec);
13751 alc269_lifebook_mic_autoswitch(codec);
13752}
13753
84898e87 13754static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
13755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13756 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13757 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13758 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13759 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13760 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13761 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13762 {}
13763};
13764
84898e87 13765static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
13766 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13767 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13768 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13769 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13770 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13771 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13772 {}
13773};
13774
84898e87
KY
13775static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13776 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13777 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13778 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13780 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13781 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13782 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13783 {}
13784};
13785
13786static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13787 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13788 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13789 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13791 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13792 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13793 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13794 {}
13795};
13796
f53281e6
KY
13797/* toggle speaker-output according to the hp-jack state */
13798static void alc269_speaker_automute(struct hda_codec *codec)
13799{
ebb83eeb
KY
13800 struct alc_spec *spec = codec->spec;
13801 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 13802 unsigned int present;
60db6b53 13803 unsigned char bits;
f53281e6 13804
ebb83eeb 13805 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 13806 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 13807 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13808 HDA_AMP_MUTE, bits);
f53281e6 13809 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13810 HDA_AMP_MUTE, bits);
f53281e6
KY
13811}
13812
f53281e6 13813/* unsolicited event for HP jack sensing */
84898e87 13814static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 13815 unsigned int res)
f53281e6 13816{
4f5d1706
TI
13817 switch (res >> 26) {
13818 case ALC880_HP_EVENT:
f53281e6 13819 alc269_speaker_automute(codec);
4f5d1706
TI
13820 break;
13821 case ALC880_MIC_EVENT:
13822 alc_mic_automute(codec);
13823 break;
13824 }
f53281e6
KY
13825}
13826
84898e87 13827static void alc269_laptop_dmic_setup(struct hda_codec *codec)
f53281e6 13828{
4f5d1706 13829 struct alc_spec *spec = codec->spec;
20645d70
TI
13830 spec->autocfg.hp_pins[0] = 0x15;
13831 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13832 spec->ext_mic.pin = 0x18;
13833 spec->ext_mic.mux_idx = 0;
13834 spec->int_mic.pin = 0x12;
13835 spec->int_mic.mux_idx = 5;
13836 spec->auto_mic = 1;
f53281e6
KY
13837}
13838
84898e87
KY
13839static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13840{
13841 struct alc_spec *spec = codec->spec;
20645d70
TI
13842 spec->autocfg.hp_pins[0] = 0x15;
13843 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
13844 spec->ext_mic.pin = 0x18;
13845 spec->ext_mic.mux_idx = 0;
13846 spec->int_mic.pin = 0x12;
13847 spec->int_mic.mux_idx = 6;
13848 spec->auto_mic = 1;
13849}
13850
13851static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 13852{
4f5d1706 13853 struct alc_spec *spec = codec->spec;
20645d70
TI
13854 spec->autocfg.hp_pins[0] = 0x15;
13855 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13856 spec->ext_mic.pin = 0x18;
13857 spec->ext_mic.mux_idx = 0;
13858 spec->int_mic.pin = 0x19;
13859 spec->int_mic.mux_idx = 1;
13860 spec->auto_mic = 1;
f53281e6
KY
13861}
13862
84898e87 13863static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
13864{
13865 alc269_speaker_automute(codec);
4f5d1706 13866 alc_mic_automute(codec);
f53281e6
KY
13867}
13868
60db6b53
KY
13869/*
13870 * generic initialization of ADC, input mixers and output mixers
13871 */
13872static struct hda_verb alc269_init_verbs[] = {
13873 /*
13874 * Unmute ADC0 and set the default input to mic-in
13875 */
84898e87 13876 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
13877
13878 /*
84898e87 13879 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
13880 */
13881 /* set vol=0 to output mixers */
13882 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13883 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13884
13885 /* set up input amps for analog loopback */
13886 /* Amp Indices: DAC = 0, mixer = 1 */
13887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13890 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13893
13894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13896 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13897 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13898 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13899 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13900 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13901
13902 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13903 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 13904
84898e87
KY
13905 /* FIXME: use Mux-type input source selection */
13906 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13907 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13908 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 13909
84898e87
KY
13910 /* set EAPD */
13911 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13912 { }
13913};
13914
13915static struct hda_verb alc269vb_init_verbs[] = {
13916 /*
13917 * Unmute ADC0 and set the default input to mic-in
13918 */
13919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13920
13921 /*
13922 * Set up output mixers (0x02 - 0x03)
13923 */
13924 /* set vol=0 to output mixers */
13925 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13926 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13927
13928 /* set up input amps for analog loopback */
13929 /* Amp Indices: DAC = 0, mixer = 1 */
13930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13932 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13934 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13935 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13936
13937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13938 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13939 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13940 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13941 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13942 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13943 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13944
13945 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13946 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13947
13948 /* FIXME: use Mux-type input source selection */
60db6b53
KY
13949 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13950 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 13951 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
13952
13953 /* set EAPD */
13954 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
13955 { }
13956};
13957
9d0b71b1
TI
13958#define alc269_auto_create_multi_out_ctls \
13959 alc268_auto_create_multi_out_ctls
05f5f477
TI
13960#define alc269_auto_create_input_ctls \
13961 alc268_auto_create_input_ctls
f6a92248
KY
13962
13963#ifdef CONFIG_SND_HDA_POWER_SAVE
13964#define alc269_loopbacks alc880_loopbacks
13965#endif
13966
def319f9 13967/* pcm configuration: identical with ALC880 */
f6a92248
KY
13968#define alc269_pcm_analog_playback alc880_pcm_analog_playback
13969#define alc269_pcm_analog_capture alc880_pcm_analog_capture
13970#define alc269_pcm_digital_playback alc880_pcm_digital_playback
13971#define alc269_pcm_digital_capture alc880_pcm_digital_capture
13972
f03d3115
TI
13973static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13974 .substreams = 1,
13975 .channels_min = 2,
13976 .channels_max = 8,
13977 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13978 /* NID is set in alc_build_pcms */
13979 .ops = {
13980 .open = alc880_playback_pcm_open,
13981 .prepare = alc880_playback_pcm_prepare,
13982 .cleanup = alc880_playback_pcm_cleanup
13983 },
13984};
13985
13986static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13987 .substreams = 1,
13988 .channels_min = 2,
13989 .channels_max = 2,
13990 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13991 /* NID is set in alc_build_pcms */
13992};
13993
ad35879a
TI
13994#ifdef CONFIG_SND_HDA_POWER_SAVE
13995static int alc269_mic2_for_mute_led(struct hda_codec *codec)
13996{
13997 switch (codec->subsystem_id) {
13998 case 0x103c1586:
13999 return 1;
14000 }
14001 return 0;
14002}
14003
14004static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14005{
14006 /* update mute-LED according to the speaker mute state */
14007 if (nid == 0x01 || nid == 0x14) {
14008 int pinval;
14009 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14010 HDA_AMP_MUTE)
14011 pinval = 0x24;
14012 else
14013 pinval = 0x20;
14014 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14015 snd_hda_codec_update_cache(codec, 0x19, 0,
14016 AC_VERB_SET_PIN_WIDGET_CONTROL,
14017 pinval);
ad35879a
TI
14018 }
14019 return alc_check_power_status(codec, nid);
14020}
14021#endif /* CONFIG_SND_HDA_POWER_SAVE */
14022
f6a92248
KY
14023/*
14024 * BIOS auto configuration
14025 */
14026static int alc269_parse_auto_config(struct hda_codec *codec)
14027{
14028 struct alc_spec *spec = codec->spec;
cfb9fb55 14029 int err;
f6a92248
KY
14030 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14031
14032 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14033 alc269_ignore);
14034 if (err < 0)
14035 return err;
14036
14037 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14038 if (err < 0)
14039 return err;
05f5f477 14040 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14041 if (err < 0)
14042 return err;
14043
14044 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14045
0852d7a6 14046 if (spec->autocfg.dig_outs)
f6a92248
KY
14047 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
14048
603c4019 14049 if (spec->kctls.list)
d88897ea 14050 add_mixer(spec, spec->kctls.list);
f6a92248 14051
84898e87
KY
14052 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14053 add_verb(spec, alc269vb_init_verbs);
6227cdce 14054 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14055 } else {
14056 add_verb(spec, alc269_init_verbs);
6227cdce 14057 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14058 }
14059
f6a92248 14060 spec->num_mux_defs = 1;
61b9b9b1 14061 spec->input_mux = &spec->private_imux[0];
6694635d
TI
14062 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14063 sizeof(alc269_adc_candidates));
14064
e01bf509 14065 /* set default input source */
6694635d 14066 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14067 0, AC_VERB_SET_CONNECT_SEL,
14068 spec->input_mux->items[0].index);
f6a92248
KY
14069
14070 err = alc_auto_add_mic_boost(codec);
14071 if (err < 0)
14072 return err;
14073
7e0e44d4 14074 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14075 set_capture_mixer(codec);
f53281e6 14076
f6a92248
KY
14077 return 1;
14078}
14079
e9af4f36
TI
14080#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14081#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14082#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14083
14084
14085/* init callback for auto-configuration model -- overriding the default init */
14086static void alc269_auto_init(struct hda_codec *codec)
14087{
f6c7e546 14088 struct alc_spec *spec = codec->spec;
f6a92248
KY
14089 alc269_auto_init_multi_out(codec);
14090 alc269_auto_init_hp_out(codec);
14091 alc269_auto_init_analog_input(codec);
f6c7e546 14092 if (spec->unsol_event)
7fb0d78f 14093 alc_inithook(codec);
f6a92248
KY
14094}
14095
14096/*
14097 * configuration and preset
14098 */
14099static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14100 [ALC269_BASIC] = "basic",
2922c9af 14101 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14102 [ALC269_AMIC] = "laptop-amic",
14103 [ALC269_DMIC] = "laptop-dmic",
64154835 14104 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14105 [ALC269_LIFEBOOK] = "lifebook",
14106 [ALC269_AUTO] = "auto",
f6a92248
KY
14107};
14108
14109static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14110 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14111 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14112 ALC269_AMIC),
14113 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14114 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14115 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14116 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14117 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14118 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14119 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14120 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14121 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14122 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14123 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14124 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14125 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14126 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14127 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14128 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14129 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14130 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14131 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14132 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14133 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14134 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14135 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14136 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14137 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14138 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14139 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14140 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14141 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14142 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14143 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14144 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14145 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14146 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14147 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14148 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14149 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14150 ALC269_DMIC),
60db6b53 14151 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14152 ALC269_DMIC),
14153 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14154 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
61c2d2b5 14155 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
64154835 14156 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14157 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14158 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14159 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14160 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14161 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14162 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14163 {}
14164};
14165
14166static struct alc_config_preset alc269_presets[] = {
14167 [ALC269_BASIC] = {
f9e336f6 14168 .mixers = { alc269_base_mixer },
f6a92248
KY
14169 .init_verbs = { alc269_init_verbs },
14170 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14171 .dac_nids = alc269_dac_nids,
14172 .hp_nid = 0x03,
14173 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14174 .channel_mode = alc269_modes,
14175 .input_mux = &alc269_capture_source,
14176 },
60db6b53
KY
14177 [ALC269_QUANTA_FL1] = {
14178 .mixers = { alc269_quanta_fl1_mixer },
14179 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14180 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14181 .dac_nids = alc269_dac_nids,
14182 .hp_nid = 0x03,
14183 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14184 .channel_mode = alc269_modes,
14185 .input_mux = &alc269_capture_source,
14186 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14187 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14188 .init_hook = alc269_quanta_fl1_init_hook,
14189 },
84898e87
KY
14190 [ALC269_AMIC] = {
14191 .mixers = { alc269_laptop_mixer },
14192 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14193 .init_verbs = { alc269_init_verbs,
84898e87 14194 alc269_laptop_amic_init_verbs },
f53281e6
KY
14195 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14196 .dac_nids = alc269_dac_nids,
14197 .hp_nid = 0x03,
14198 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14199 .channel_mode = alc269_modes,
84898e87
KY
14200 .unsol_event = alc269_laptop_unsol_event,
14201 .setup = alc269_laptop_amic_setup,
14202 .init_hook = alc269_laptop_inithook,
f53281e6 14203 },
84898e87
KY
14204 [ALC269_DMIC] = {
14205 .mixers = { alc269_laptop_mixer },
14206 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14207 .init_verbs = { alc269_init_verbs,
84898e87
KY
14208 alc269_laptop_dmic_init_verbs },
14209 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14210 .dac_nids = alc269_dac_nids,
14211 .hp_nid = 0x03,
14212 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14213 .channel_mode = alc269_modes,
14214 .unsol_event = alc269_laptop_unsol_event,
14215 .setup = alc269_laptop_dmic_setup,
14216 .init_hook = alc269_laptop_inithook,
14217 },
14218 [ALC269VB_AMIC] = {
14219 .mixers = { alc269vb_laptop_mixer },
14220 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14221 .init_verbs = { alc269vb_init_verbs,
14222 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14223 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14224 .dac_nids = alc269_dac_nids,
14225 .hp_nid = 0x03,
14226 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14227 .channel_mode = alc269_modes,
84898e87
KY
14228 .unsol_event = alc269_laptop_unsol_event,
14229 .setup = alc269_laptop_amic_setup,
14230 .init_hook = alc269_laptop_inithook,
14231 },
14232 [ALC269VB_DMIC] = {
14233 .mixers = { alc269vb_laptop_mixer },
14234 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14235 .init_verbs = { alc269vb_init_verbs,
14236 alc269vb_laptop_dmic_init_verbs },
14237 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14238 .dac_nids = alc269_dac_nids,
14239 .hp_nid = 0x03,
14240 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14241 .channel_mode = alc269_modes,
14242 .unsol_event = alc269_laptop_unsol_event,
14243 .setup = alc269vb_laptop_dmic_setup,
14244 .init_hook = alc269_laptop_inithook,
f53281e6 14245 },
26f5df26 14246 [ALC269_FUJITSU] = {
45bdd1c1 14247 .mixers = { alc269_fujitsu_mixer },
84898e87 14248 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14249 .init_verbs = { alc269_init_verbs,
84898e87 14250 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14251 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14252 .dac_nids = alc269_dac_nids,
14253 .hp_nid = 0x03,
14254 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14255 .channel_mode = alc269_modes,
84898e87
KY
14256 .unsol_event = alc269_laptop_unsol_event,
14257 .setup = alc269_laptop_dmic_setup,
14258 .init_hook = alc269_laptop_inithook,
26f5df26 14259 },
64154835
TV
14260 [ALC269_LIFEBOOK] = {
14261 .mixers = { alc269_lifebook_mixer },
14262 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14263 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14264 .dac_nids = alc269_dac_nids,
14265 .hp_nid = 0x03,
14266 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14267 .channel_mode = alc269_modes,
14268 .input_mux = &alc269_capture_source,
14269 .unsol_event = alc269_lifebook_unsol_event,
14270 .init_hook = alc269_lifebook_init_hook,
14271 },
f6a92248
KY
14272};
14273
14274static int patch_alc269(struct hda_codec *codec)
14275{
14276 struct alc_spec *spec;
14277 int board_config;
14278 int err;
84898e87 14279 int is_alc269vb = 0;
f6a92248
KY
14280
14281 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14282 if (spec == NULL)
14283 return -ENOMEM;
14284
14285 codec->spec = spec;
14286
da00c244
KY
14287 alc_auto_parse_customize_define(codec);
14288
274693f3 14289 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14290 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14291 spec->cdefine.platform_type == 1)
14292 alc_codec_rename(codec, "ALC271X");
14293 else
14294 alc_codec_rename(codec, "ALC259");
84898e87 14295 is_alc269vb = 1;
c027ddcd
KY
14296 } else
14297 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14298
f6a92248
KY
14299 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14300 alc269_models,
14301 alc269_cfg_tbl);
14302
14303 if (board_config < 0) {
9a11f1aa
TI
14304 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14305 codec->chip_name);
f6a92248
KY
14306 board_config = ALC269_AUTO;
14307 }
14308
14309 if (board_config == ALC269_AUTO) {
14310 /* automatic parse from the BIOS config */
14311 err = alc269_parse_auto_config(codec);
14312 if (err < 0) {
14313 alc_free(codec);
14314 return err;
14315 } else if (!err) {
14316 printk(KERN_INFO
14317 "hda_codec: Cannot set up configuration "
14318 "from BIOS. Using base mode...\n");
14319 board_config = ALC269_BASIC;
14320 }
14321 }
14322
680cd536
KK
14323 err = snd_hda_attach_beep_device(codec, 0x1);
14324 if (err < 0) {
14325 alc_free(codec);
14326 return err;
14327 }
14328
f6a92248 14329 if (board_config != ALC269_AUTO)
e9c364c0 14330 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14331
84898e87 14332 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14333 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14334 * fix the sample rate of analog I/O to 44.1kHz
14335 */
14336 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14337 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14338 } else {
14339 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14340 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14341 }
f6a92248
KY
14342 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14343 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14344
6694635d
TI
14345 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14346 if (!is_alc269vb) {
14347 spec->adc_nids = alc269_adc_nids;
14348 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14349 spec->capsrc_nids = alc269_capsrc_nids;
14350 } else {
14351 spec->adc_nids = alc269vb_adc_nids;
14352 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14353 spec->capsrc_nids = alc269vb_capsrc_nids;
14354 }
84898e87
KY
14355 }
14356
f9e336f6 14357 if (!spec->cap_mixer)
b59bdf3b 14358 set_capture_mixer(codec);
da00c244
KY
14359 if (spec->cdefine.enable_pcbeep)
14360 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14361
100d5eb3
TI
14362 spec->vmaster_nid = 0x02;
14363
f6a92248
KY
14364 codec->patch_ops = alc_patch_ops;
14365 if (board_config == ALC269_AUTO)
14366 spec->init_hook = alc269_auto_init;
14367#ifdef CONFIG_SND_HDA_POWER_SAVE
14368 if (!spec->loopback.amplist)
14369 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14370 if (alc269_mic2_for_mute_led(codec))
14371 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14372#endif
14373
14374 return 0;
14375}
14376
df694daa
KY
14377/*
14378 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14379 */
14380
14381/*
14382 * set the path ways for 2 channel output
14383 * need to set the codec line out and mic 1 pin widgets to inputs
14384 */
14385static struct hda_verb alc861_threestack_ch2_init[] = {
14386 /* set pin widget 1Ah (line in) for input */
14387 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14388 /* set pin widget 18h (mic1/2) for input, for mic also enable
14389 * the vref
14390 */
df694daa
KY
14391 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14392
9c7f852e
TI
14393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14394#if 0
14395 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14396 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14397#endif
df694daa
KY
14398 { } /* end */
14399};
14400/*
14401 * 6ch mode
14402 * need to set the codec line out and mic 1 pin widgets to outputs
14403 */
14404static struct hda_verb alc861_threestack_ch6_init[] = {
14405 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14406 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14407 /* set pin widget 18h (mic1) for output (CLFE)*/
14408 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14409
14410 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14411 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14412
9c7f852e
TI
14413 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14414#if 0
14415 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14416 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14417#endif
df694daa
KY
14418 { } /* end */
14419};
14420
14421static struct hda_channel_mode alc861_threestack_modes[2] = {
14422 { 2, alc861_threestack_ch2_init },
14423 { 6, alc861_threestack_ch6_init },
14424};
22309c3e
TI
14425/* Set mic1 as input and unmute the mixer */
14426static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14427 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14428 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14429 { } /* end */
14430};
14431/* Set mic1 as output and mute mixer */
14432static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14433 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14434 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14435 { } /* end */
14436};
14437
14438static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14439 { 2, alc861_uniwill_m31_ch2_init },
14440 { 4, alc861_uniwill_m31_ch4_init },
14441};
df694daa 14442
7cdbff94
MD
14443/* Set mic1 and line-in as input and unmute the mixer */
14444static struct hda_verb alc861_asus_ch2_init[] = {
14445 /* set pin widget 1Ah (line in) for input */
14446 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14447 /* set pin widget 18h (mic1/2) for input, for mic also enable
14448 * the vref
14449 */
7cdbff94
MD
14450 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14451
14452 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14453#if 0
14454 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14455 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14456#endif
14457 { } /* end */
14458};
14459/* Set mic1 nad line-in as output and mute mixer */
14460static struct hda_verb alc861_asus_ch6_init[] = {
14461 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14462 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14463 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14464 /* set pin widget 18h (mic1) for output (CLFE)*/
14465 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14466 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14467 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14468 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14469
14470 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14471#if 0
14472 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14473 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14474#endif
14475 { } /* end */
14476};
14477
14478static struct hda_channel_mode alc861_asus_modes[2] = {
14479 { 2, alc861_asus_ch2_init },
14480 { 6, alc861_asus_ch6_init },
14481};
14482
df694daa
KY
14483/* patch-ALC861 */
14484
14485static struct snd_kcontrol_new alc861_base_mixer[] = {
14486 /* output mixer control */
14487 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14488 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14489 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14490 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14491 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14492
14493 /*Input mixer control */
14494 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14495 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14496 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14497 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14498 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14499 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14501 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14502 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14503 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14504
df694daa
KY
14505 { } /* end */
14506};
14507
14508static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14509 /* output mixer control */
14510 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14511 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14512 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14513 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14514 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14515
14516 /* Input mixer control */
14517 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14518 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14519 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14520 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14521 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14522 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14523 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14524 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14525 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14526 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14527
df694daa
KY
14528 {
14529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14530 .name = "Channel Mode",
14531 .info = alc_ch_mode_info,
14532 .get = alc_ch_mode_get,
14533 .put = alc_ch_mode_put,
14534 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14535 },
14536 { } /* end */
a53d1aec
TD
14537};
14538
d1d985f0 14539static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14540 /* output mixer control */
14541 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14543 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14544
a53d1aec 14545 { } /* end */
f12ab1e0 14546};
a53d1aec 14547
22309c3e
TI
14548static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14549 /* output mixer control */
14550 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14551 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14552 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14553 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14554 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14555
14556 /* Input mixer control */
14557 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14558 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14559 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14560 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14561 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14562 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14564 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14565 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14567
22309c3e
TI
14568 {
14569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14570 .name = "Channel Mode",
14571 .info = alc_ch_mode_info,
14572 .get = alc_ch_mode_get,
14573 .put = alc_ch_mode_put,
14574 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14575 },
14576 { } /* end */
f12ab1e0 14577};
7cdbff94
MD
14578
14579static struct snd_kcontrol_new alc861_asus_mixer[] = {
14580 /* output mixer control */
14581 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14582 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14583 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14584 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14585 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14586
14587 /* Input mixer control */
14588 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14589 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14590 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14591 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14592 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14593 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14594 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14595 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14596 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14598
7cdbff94
MD
14599 {
14600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14601 .name = "Channel Mode",
14602 .info = alc_ch_mode_info,
14603 .get = alc_ch_mode_get,
14604 .put = alc_ch_mode_put,
14605 .private_value = ARRAY_SIZE(alc861_asus_modes),
14606 },
14607 { }
56bb0cab
TI
14608};
14609
14610/* additional mixer */
d1d985f0 14611static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14612 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14613 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14614 { }
14615};
7cdbff94 14616
df694daa
KY
14617/*
14618 * generic initialization of ADC, input mixers and output mixers
14619 */
14620static struct hda_verb alc861_base_init_verbs[] = {
14621 /*
14622 * Unmute ADC0 and set the default input to mic-in
14623 */
14624 /* port-A for surround (rear panel) */
14625 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14626 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14627 /* port-B for mic-in (rear panel) with vref */
14628 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14629 /* port-C for line-in (rear panel) */
14630 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14631 /* port-D for Front */
14632 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14633 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14634 /* port-E for HP out (front panel) */
14635 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14636 /* route front PCM to HP */
9dece1d7 14637 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14638 /* port-F for mic-in (front panel) with vref */
14639 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14640 /* port-G for CLFE (rear panel) */
14641 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14642 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14643 /* port-H for side (rear panel) */
14644 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14645 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14646 /* CD-in */
14647 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14648 /* route front mic to ADC1*/
14649 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14651
df694daa
KY
14652 /* Unmute DAC0~3 & spdif out*/
14653 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14654 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14655 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14656 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14658
df694daa
KY
14659 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14660 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14661 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14662 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14663 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14664
df694daa
KY
14665 /* Unmute Stereo Mixer 15 */
14666 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14668 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14669 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14670
14671 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14672 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14673 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14674 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14675 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14677 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14678 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14679 /* hp used DAC 3 (Front) */
14680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14682
14683 { }
14684};
14685
14686static struct hda_verb alc861_threestack_init_verbs[] = {
14687 /*
14688 * Unmute ADC0 and set the default input to mic-in
14689 */
14690 /* port-A for surround (rear panel) */
14691 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14692 /* port-B for mic-in (rear panel) with vref */
14693 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14694 /* port-C for line-in (rear panel) */
14695 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14696 /* port-D for Front */
14697 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14698 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14699 /* port-E for HP out (front panel) */
14700 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14701 /* route front PCM to HP */
9dece1d7 14702 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14703 /* port-F for mic-in (front panel) with vref */
14704 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14705 /* port-G for CLFE (rear panel) */
14706 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14707 /* port-H for side (rear panel) */
14708 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14709 /* CD-in */
14710 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14711 /* route front mic to ADC1*/
14712 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14714 /* Unmute DAC0~3 & spdif out*/
14715 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14716 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14717 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14718 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14720
df694daa
KY
14721 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14722 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14723 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14724 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14725 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14726
df694daa
KY
14727 /* Unmute Stereo Mixer 15 */
14728 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14731 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14732
14733 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14734 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14735 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14736 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14741 /* hp used DAC 3 (Front) */
14742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14743 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14744 { }
14745};
22309c3e
TI
14746
14747static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14748 /*
14749 * Unmute ADC0 and set the default input to mic-in
14750 */
14751 /* port-A for surround (rear panel) */
14752 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14753 /* port-B for mic-in (rear panel) with vref */
14754 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14755 /* port-C for line-in (rear panel) */
14756 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14757 /* port-D for Front */
14758 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14759 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14760 /* port-E for HP out (front panel) */
f12ab1e0
TI
14761 /* this has to be set to VREF80 */
14762 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 14763 /* route front PCM to HP */
9dece1d7 14764 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
14765 /* port-F for mic-in (front panel) with vref */
14766 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14767 /* port-G for CLFE (rear panel) */
14768 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14769 /* port-H for side (rear panel) */
14770 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14771 /* CD-in */
14772 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14773 /* route front mic to ADC1*/
14774 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14775 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14776 /* Unmute DAC0~3 & spdif out*/
14777 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14778 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14779 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14780 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14782
22309c3e
TI
14783 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14784 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14785 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14786 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14787 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14788
22309c3e
TI
14789 /* Unmute Stereo Mixer 15 */
14790 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14791 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14792 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
14794
14795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14798 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14799 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14800 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14802 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14803 /* hp used DAC 3 (Front) */
14804 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
14805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14806 { }
14807};
14808
7cdbff94
MD
14809static struct hda_verb alc861_asus_init_verbs[] = {
14810 /*
14811 * Unmute ADC0 and set the default input to mic-in
14812 */
f12ab1e0
TI
14813 /* port-A for surround (rear panel)
14814 * according to codec#0 this is the HP jack
14815 */
7cdbff94
MD
14816 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14817 /* route front PCM to HP */
14818 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14819 /* port-B for mic-in (rear panel) with vref */
14820 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14821 /* port-C for line-in (rear panel) */
14822 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14823 /* port-D for Front */
14824 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14825 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14826 /* port-E for HP out (front panel) */
f12ab1e0
TI
14827 /* this has to be set to VREF80 */
14828 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 14829 /* route front PCM to HP */
9dece1d7 14830 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
14831 /* port-F for mic-in (front panel) with vref */
14832 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14833 /* port-G for CLFE (rear panel) */
14834 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14835 /* port-H for side (rear panel) */
14836 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14837 /* CD-in */
14838 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14839 /* route front mic to ADC1*/
14840 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14841 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14842 /* Unmute DAC0~3 & spdif out*/
14843 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14844 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14845 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14846 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14848 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14849 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14850 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14851 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14852 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14853
7cdbff94
MD
14854 /* Unmute Stereo Mixer 15 */
14855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14857 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
14859
14860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14861 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14862 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14863 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14864 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14865 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14866 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14867 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14868 /* hp used DAC 3 (Front) */
14869 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
14870 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14871 { }
14872};
14873
56bb0cab
TI
14874/* additional init verbs for ASUS laptops */
14875static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14876 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14877 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14878 { }
14879};
7cdbff94 14880
df694daa
KY
14881/*
14882 * generic initialization of ADC, input mixers and output mixers
14883 */
14884static struct hda_verb alc861_auto_init_verbs[] = {
14885 /*
14886 * Unmute ADC0 and set the default input to mic-in
14887 */
f12ab1e0 14888 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 14889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14890
df694daa
KY
14891 /* Unmute DAC0~3 & spdif out*/
14892 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14893 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14894 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14895 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14897
df694daa
KY
14898 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14899 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14900 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14901 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14902 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14903
df694daa
KY
14904 /* Unmute Stereo Mixer 15 */
14905 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14906 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14909
1c20930a
TI
14910 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14911 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14912 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14913 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14914 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14916 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14917 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
14918
14919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14921 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14922 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
14923 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14924 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14925 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14926 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 14927
f12ab1e0 14928 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
14929
14930 { }
14931};
14932
a53d1aec
TD
14933static struct hda_verb alc861_toshiba_init_verbs[] = {
14934 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 14935
a53d1aec
TD
14936 { }
14937};
14938
14939/* toggle speaker-output according to the hp-jack state */
14940static void alc861_toshiba_automute(struct hda_codec *codec)
14941{
864f92be 14942 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 14943
47fd830a
TI
14944 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14945 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14946 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14947 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
14948}
14949
14950static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14951 unsigned int res)
14952{
a53d1aec
TD
14953 if ((res >> 26) == ALC880_HP_EVENT)
14954 alc861_toshiba_automute(codec);
14955}
14956
def319f9 14957/* pcm configuration: identical with ALC880 */
df694daa
KY
14958#define alc861_pcm_analog_playback alc880_pcm_analog_playback
14959#define alc861_pcm_analog_capture alc880_pcm_analog_capture
14960#define alc861_pcm_digital_playback alc880_pcm_digital_playback
14961#define alc861_pcm_digital_capture alc880_pcm_digital_capture
14962
14963
14964#define ALC861_DIGOUT_NID 0x07
14965
14966static struct hda_channel_mode alc861_8ch_modes[1] = {
14967 { 8, NULL }
14968};
14969
14970static hda_nid_t alc861_dac_nids[4] = {
14971 /* front, surround, clfe, side */
14972 0x03, 0x06, 0x05, 0x04
14973};
14974
9c7f852e
TI
14975static hda_nid_t alc660_dac_nids[3] = {
14976 /* front, clfe, surround */
14977 0x03, 0x05, 0x06
14978};
14979
df694daa
KY
14980static hda_nid_t alc861_adc_nids[1] = {
14981 /* ADC0-2 */
14982 0x08,
14983};
14984
14985static struct hda_input_mux alc861_capture_source = {
14986 .num_items = 5,
14987 .items = {
14988 { "Mic", 0x0 },
14989 { "Front Mic", 0x3 },
14990 { "Line", 0x1 },
14991 { "CD", 0x4 },
14992 { "Mixer", 0x5 },
14993 },
14994};
14995
1c20930a
TI
14996static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14997{
14998 struct alc_spec *spec = codec->spec;
14999 hda_nid_t mix, srcs[5];
15000 int i, j, num;
15001
15002 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15003 return 0;
15004 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15005 if (num < 0)
15006 return 0;
15007 for (i = 0; i < num; i++) {
15008 unsigned int type;
a22d543a 15009 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15010 if (type != AC_WID_AUD_OUT)
15011 continue;
15012 for (j = 0; j < spec->multiout.num_dacs; j++)
15013 if (spec->multiout.dac_nids[j] == srcs[i])
15014 break;
15015 if (j >= spec->multiout.num_dacs)
15016 return srcs[i];
15017 }
15018 return 0;
15019}
15020
df694daa 15021/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15022static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15023 const struct auto_pin_cfg *cfg)
df694daa 15024{
1c20930a 15025 struct alc_spec *spec = codec->spec;
df694daa 15026 int i;
1c20930a 15027 hda_nid_t nid, dac;
df694daa
KY
15028
15029 spec->multiout.dac_nids = spec->private_dac_nids;
15030 for (i = 0; i < cfg->line_outs; i++) {
15031 nid = cfg->line_out_pins[i];
1c20930a
TI
15032 dac = alc861_look_for_dac(codec, nid);
15033 if (!dac)
15034 continue;
15035 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15036 }
df694daa
KY
15037 return 0;
15038}
15039
1c20930a
TI
15040static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15041 hda_nid_t nid, unsigned int chs)
15042{
0afe5f89 15043 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15044 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15045}
15046
df694daa 15047/* add playback controls from the parsed DAC table */
1c20930a 15048static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15049 const struct auto_pin_cfg *cfg)
15050{
1c20930a 15051 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15052 static const char *chname[4] = {
15053 "Front", "Surround", NULL /*CLFE*/, "Side"
15054 };
df694daa 15055 hda_nid_t nid;
1c20930a
TI
15056 int i, err;
15057
15058 if (cfg->line_outs == 1) {
15059 const char *pfx = NULL;
15060 if (!cfg->hp_outs)
15061 pfx = "Master";
15062 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15063 pfx = "Speaker";
15064 if (pfx) {
15065 nid = spec->multiout.dac_nids[0];
15066 return alc861_create_out_sw(codec, pfx, nid, 3);
15067 }
15068 }
df694daa
KY
15069
15070 for (i = 0; i < cfg->line_outs; i++) {
15071 nid = spec->multiout.dac_nids[i];
f12ab1e0 15072 if (!nid)
df694daa 15073 continue;
1c20930a 15074 if (i == 2) {
df694daa 15075 /* Center/LFE */
1c20930a 15076 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15077 if (err < 0)
df694daa 15078 return err;
1c20930a 15079 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15080 if (err < 0)
df694daa
KY
15081 return err;
15082 } else {
1c20930a 15083 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15084 if (err < 0)
df694daa
KY
15085 return err;
15086 }
15087 }
15088 return 0;
15089}
15090
1c20930a 15091static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15092{
1c20930a 15093 struct alc_spec *spec = codec->spec;
df694daa
KY
15094 int err;
15095 hda_nid_t nid;
15096
f12ab1e0 15097 if (!pin)
df694daa
KY
15098 return 0;
15099
15100 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15101 nid = alc861_look_for_dac(codec, pin);
15102 if (nid) {
15103 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15104 if (err < 0)
15105 return err;
15106 spec->multiout.hp_nid = nid;
15107 }
df694daa
KY
15108 }
15109 return 0;
15110}
15111
15112/* create playback/capture controls for input pins */
05f5f477 15113static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15114 const struct auto_pin_cfg *cfg)
df694daa 15115{
05f5f477 15116 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15117}
15118
f12ab1e0
TI
15119static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15120 hda_nid_t nid,
1c20930a 15121 int pin_type, hda_nid_t dac)
df694daa 15122{
1c20930a
TI
15123 hda_nid_t mix, srcs[5];
15124 int i, num;
15125
564c5bea
JL
15126 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15127 pin_type);
1c20930a 15128 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15129 AMP_OUT_UNMUTE);
1c20930a
TI
15130 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15131 return;
15132 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15133 if (num < 0)
15134 return;
15135 for (i = 0; i < num; i++) {
15136 unsigned int mute;
15137 if (srcs[i] == dac || srcs[i] == 0x15)
15138 mute = AMP_IN_UNMUTE(i);
15139 else
15140 mute = AMP_IN_MUTE(i);
15141 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15142 mute);
15143 }
df694daa
KY
15144}
15145
15146static void alc861_auto_init_multi_out(struct hda_codec *codec)
15147{
15148 struct alc_spec *spec = codec->spec;
15149 int i;
15150
15151 for (i = 0; i < spec->autocfg.line_outs; i++) {
15152 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15153 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15154 if (nid)
baba8ee9 15155 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15156 spec->multiout.dac_nids[i]);
df694daa
KY
15157 }
15158}
15159
15160static void alc861_auto_init_hp_out(struct hda_codec *codec)
15161{
15162 struct alc_spec *spec = codec->spec;
df694daa 15163
15870f05
TI
15164 if (spec->autocfg.hp_outs)
15165 alc861_auto_set_output_and_unmute(codec,
15166 spec->autocfg.hp_pins[0],
15167 PIN_HP,
1c20930a 15168 spec->multiout.hp_nid);
15870f05
TI
15169 if (spec->autocfg.speaker_outs)
15170 alc861_auto_set_output_and_unmute(codec,
15171 spec->autocfg.speaker_pins[0],
15172 PIN_OUT,
1c20930a 15173 spec->multiout.dac_nids[0]);
df694daa
KY
15174}
15175
15176static void alc861_auto_init_analog_input(struct hda_codec *codec)
15177{
15178 struct alc_spec *spec = codec->spec;
15179 int i;
15180
15181 for (i = 0; i < AUTO_PIN_LAST; i++) {
15182 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15183 if (nid >= 0x0c && nid <= 0x11)
15184 alc_set_input_pin(codec, nid, i);
df694daa
KY
15185 }
15186}
15187
15188/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15189/* return 1 if successful, 0 if the proper config is not found,
15190 * or a negative error code
15191 */
df694daa
KY
15192static int alc861_parse_auto_config(struct hda_codec *codec)
15193{
15194 struct alc_spec *spec = codec->spec;
15195 int err;
15196 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15197
f12ab1e0
TI
15198 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15199 alc861_ignore);
15200 if (err < 0)
df694daa 15201 return err;
f12ab1e0 15202 if (!spec->autocfg.line_outs)
df694daa
KY
15203 return 0; /* can't find valid BIOS pin config */
15204
1c20930a 15205 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15206 if (err < 0)
15207 return err;
1c20930a 15208 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15209 if (err < 0)
15210 return err;
1c20930a 15211 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15212 if (err < 0)
15213 return err;
05f5f477 15214 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15215 if (err < 0)
df694daa
KY
15216 return err;
15217
15218 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15219
0852d7a6 15220 if (spec->autocfg.dig_outs)
df694daa
KY
15221 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15222
603c4019 15223 if (spec->kctls.list)
d88897ea 15224 add_mixer(spec, spec->kctls.list);
df694daa 15225
d88897ea 15226 add_verb(spec, alc861_auto_init_verbs);
df694daa 15227
a1e8d2da 15228 spec->num_mux_defs = 1;
61b9b9b1 15229 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15230
15231 spec->adc_nids = alc861_adc_nids;
15232 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15233 set_capture_mixer(codec);
df694daa 15234
6227cdce 15235 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15236
df694daa
KY
15237 return 1;
15238}
15239
ae6b813a
TI
15240/* additional initialization for auto-configuration model */
15241static void alc861_auto_init(struct hda_codec *codec)
df694daa 15242{
f6c7e546 15243 struct alc_spec *spec = codec->spec;
df694daa
KY
15244 alc861_auto_init_multi_out(codec);
15245 alc861_auto_init_hp_out(codec);
15246 alc861_auto_init_analog_input(codec);
f6c7e546 15247 if (spec->unsol_event)
7fb0d78f 15248 alc_inithook(codec);
df694daa
KY
15249}
15250
cb53c626
TI
15251#ifdef CONFIG_SND_HDA_POWER_SAVE
15252static struct hda_amp_list alc861_loopbacks[] = {
15253 { 0x15, HDA_INPUT, 0 },
15254 { 0x15, HDA_INPUT, 1 },
15255 { 0x15, HDA_INPUT, 2 },
15256 { 0x15, HDA_INPUT, 3 },
15257 { } /* end */
15258};
15259#endif
15260
df694daa
KY
15261
15262/*
15263 * configuration and preset
15264 */
f5fcc13c
TI
15265static const char *alc861_models[ALC861_MODEL_LAST] = {
15266 [ALC861_3ST] = "3stack",
15267 [ALC660_3ST] = "3stack-660",
15268 [ALC861_3ST_DIG] = "3stack-dig",
15269 [ALC861_6ST_DIG] = "6stack-dig",
15270 [ALC861_UNIWILL_M31] = "uniwill-m31",
15271 [ALC861_TOSHIBA] = "toshiba",
15272 [ALC861_ASUS] = "asus",
15273 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15274 [ALC861_AUTO] = "auto",
15275};
15276
15277static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15278 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15279 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15280 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15281 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15282 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15283 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15284 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15285 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15286 * Any other models that need this preset?
15287 */
15288 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15289 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15290 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15291 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15292 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15293 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15294 /* FIXME: the below seems conflict */
15295 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15296 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15297 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15298 {}
15299};
15300
15301static struct alc_config_preset alc861_presets[] = {
15302 [ALC861_3ST] = {
15303 .mixers = { alc861_3ST_mixer },
15304 .init_verbs = { alc861_threestack_init_verbs },
15305 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15306 .dac_nids = alc861_dac_nids,
15307 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15308 .channel_mode = alc861_threestack_modes,
4e195a7b 15309 .need_dac_fix = 1,
df694daa
KY
15310 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15311 .adc_nids = alc861_adc_nids,
15312 .input_mux = &alc861_capture_source,
15313 },
15314 [ALC861_3ST_DIG] = {
15315 .mixers = { alc861_base_mixer },
15316 .init_verbs = { alc861_threestack_init_verbs },
15317 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15318 .dac_nids = alc861_dac_nids,
15319 .dig_out_nid = ALC861_DIGOUT_NID,
15320 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15321 .channel_mode = alc861_threestack_modes,
4e195a7b 15322 .need_dac_fix = 1,
df694daa
KY
15323 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15324 .adc_nids = alc861_adc_nids,
15325 .input_mux = &alc861_capture_source,
15326 },
15327 [ALC861_6ST_DIG] = {
15328 .mixers = { alc861_base_mixer },
15329 .init_verbs = { alc861_base_init_verbs },
15330 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15331 .dac_nids = alc861_dac_nids,
15332 .dig_out_nid = ALC861_DIGOUT_NID,
15333 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15334 .channel_mode = alc861_8ch_modes,
15335 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15336 .adc_nids = alc861_adc_nids,
15337 .input_mux = &alc861_capture_source,
15338 },
9c7f852e
TI
15339 [ALC660_3ST] = {
15340 .mixers = { alc861_3ST_mixer },
15341 .init_verbs = { alc861_threestack_init_verbs },
15342 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15343 .dac_nids = alc660_dac_nids,
15344 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15345 .channel_mode = alc861_threestack_modes,
4e195a7b 15346 .need_dac_fix = 1,
9c7f852e
TI
15347 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15348 .adc_nids = alc861_adc_nids,
15349 .input_mux = &alc861_capture_source,
15350 },
22309c3e
TI
15351 [ALC861_UNIWILL_M31] = {
15352 .mixers = { alc861_uniwill_m31_mixer },
15353 .init_verbs = { alc861_uniwill_m31_init_verbs },
15354 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15355 .dac_nids = alc861_dac_nids,
15356 .dig_out_nid = ALC861_DIGOUT_NID,
15357 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15358 .channel_mode = alc861_uniwill_m31_modes,
15359 .need_dac_fix = 1,
15360 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15361 .adc_nids = alc861_adc_nids,
15362 .input_mux = &alc861_capture_source,
15363 },
a53d1aec
TD
15364 [ALC861_TOSHIBA] = {
15365 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15366 .init_verbs = { alc861_base_init_verbs,
15367 alc861_toshiba_init_verbs },
a53d1aec
TD
15368 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15369 .dac_nids = alc861_dac_nids,
15370 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15371 .channel_mode = alc883_3ST_2ch_modes,
15372 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15373 .adc_nids = alc861_adc_nids,
15374 .input_mux = &alc861_capture_source,
15375 .unsol_event = alc861_toshiba_unsol_event,
15376 .init_hook = alc861_toshiba_automute,
15377 },
7cdbff94
MD
15378 [ALC861_ASUS] = {
15379 .mixers = { alc861_asus_mixer },
15380 .init_verbs = { alc861_asus_init_verbs },
15381 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15382 .dac_nids = alc861_dac_nids,
15383 .dig_out_nid = ALC861_DIGOUT_NID,
15384 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15385 .channel_mode = alc861_asus_modes,
15386 .need_dac_fix = 1,
15387 .hp_nid = 0x06,
15388 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15389 .adc_nids = alc861_adc_nids,
15390 .input_mux = &alc861_capture_source,
15391 },
56bb0cab
TI
15392 [ALC861_ASUS_LAPTOP] = {
15393 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15394 .init_verbs = { alc861_asus_init_verbs,
15395 alc861_asus_laptop_init_verbs },
15396 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15397 .dac_nids = alc861_dac_nids,
15398 .dig_out_nid = ALC861_DIGOUT_NID,
15399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15400 .channel_mode = alc883_3ST_2ch_modes,
15401 .need_dac_fix = 1,
15402 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15403 .adc_nids = alc861_adc_nids,
15404 .input_mux = &alc861_capture_source,
15405 },
15406};
df694daa 15407
cfc9b06f
TI
15408/* Pin config fixes */
15409enum {
15410 PINFIX_FSC_AMILO_PI1505,
15411};
15412
15413static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15414 { 0x0b, 0x0221101f }, /* HP */
15415 { 0x0f, 0x90170310 }, /* speaker */
15416 { }
15417};
15418
15419static const struct alc_fixup alc861_fixups[] = {
15420 [PINFIX_FSC_AMILO_PI1505] = {
15421 .pins = alc861_fsc_amilo_pi1505_pinfix
15422 },
15423};
15424
15425static struct snd_pci_quirk alc861_fixup_tbl[] = {
15426 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15427 {}
15428};
df694daa
KY
15429
15430static int patch_alc861(struct hda_codec *codec)
15431{
15432 struct alc_spec *spec;
15433 int board_config;
15434 int err;
15435
dc041e0b 15436 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15437 if (spec == NULL)
15438 return -ENOMEM;
15439
f12ab1e0 15440 codec->spec = spec;
df694daa 15441
f5fcc13c
TI
15442 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15443 alc861_models,
15444 alc861_cfg_tbl);
9c7f852e 15445
f5fcc13c 15446 if (board_config < 0) {
9a11f1aa
TI
15447 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15448 codec->chip_name);
df694daa
KY
15449 board_config = ALC861_AUTO;
15450 }
15451
cfc9b06f
TI
15452 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
15453
df694daa
KY
15454 if (board_config == ALC861_AUTO) {
15455 /* automatic parse from the BIOS config */
15456 err = alc861_parse_auto_config(codec);
15457 if (err < 0) {
15458 alc_free(codec);
15459 return err;
f12ab1e0 15460 } else if (!err) {
9c7f852e
TI
15461 printk(KERN_INFO
15462 "hda_codec: Cannot set up configuration "
15463 "from BIOS. Using base mode...\n");
df694daa
KY
15464 board_config = ALC861_3ST_DIG;
15465 }
15466 }
15467
680cd536
KK
15468 err = snd_hda_attach_beep_device(codec, 0x23);
15469 if (err < 0) {
15470 alc_free(codec);
15471 return err;
15472 }
15473
df694daa 15474 if (board_config != ALC861_AUTO)
e9c364c0 15475 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15476
df694daa
KY
15477 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15478 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15479
df694daa
KY
15480 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15481 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15482
c7a8eb10
TI
15483 if (!spec->cap_mixer)
15484 set_capture_mixer(codec);
45bdd1c1
TI
15485 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15486
2134ea4f
TI
15487 spec->vmaster_nid = 0x03;
15488
df694daa 15489 codec->patch_ops = alc_patch_ops;
c97259df 15490 if (board_config == ALC861_AUTO) {
ae6b813a 15491 spec->init_hook = alc861_auto_init;
c97259df
DC
15492#ifdef CONFIG_SND_HDA_POWER_SAVE
15493 spec->power_hook = alc_power_eapd;
15494#endif
15495 }
cb53c626
TI
15496#ifdef CONFIG_SND_HDA_POWER_SAVE
15497 if (!spec->loopback.amplist)
15498 spec->loopback.amplist = alc861_loopbacks;
15499#endif
ea1fb29a 15500
1da177e4
LT
15501 return 0;
15502}
15503
f32610ed
JS
15504/*
15505 * ALC861-VD support
15506 *
15507 * Based on ALC882
15508 *
15509 * In addition, an independent DAC
15510 */
15511#define ALC861VD_DIGOUT_NID 0x06
15512
15513static hda_nid_t alc861vd_dac_nids[4] = {
15514 /* front, surr, clfe, side surr */
15515 0x02, 0x03, 0x04, 0x05
15516};
15517
15518/* dac_nids for ALC660vd are in a different order - according to
15519 * Realtek's driver.
def319f9 15520 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15521 * of ALC660vd codecs, but for now there is only 3stack mixer
15522 * - and it is the same as in 861vd.
15523 * adc_nids in ALC660vd are (is) the same as in 861vd
15524 */
15525static hda_nid_t alc660vd_dac_nids[3] = {
15526 /* front, rear, clfe, rear_surr */
15527 0x02, 0x04, 0x03
15528};
15529
15530static hda_nid_t alc861vd_adc_nids[1] = {
15531 /* ADC0 */
15532 0x09,
15533};
15534
e1406348
TI
15535static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15536
f32610ed
JS
15537/* input MUX */
15538/* FIXME: should be a matrix-type input source selection */
15539static struct hda_input_mux alc861vd_capture_source = {
15540 .num_items = 4,
15541 .items = {
15542 { "Mic", 0x0 },
15543 { "Front Mic", 0x1 },
15544 { "Line", 0x2 },
15545 { "CD", 0x4 },
15546 },
15547};
15548
272a527c 15549static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15550 .num_items = 2,
272a527c 15551 .items = {
b419f346
TD
15552 { "Ext Mic", 0x0 },
15553 { "Int Mic", 0x1 },
272a527c
KY
15554 },
15555};
15556
d1a991a6
KY
15557static struct hda_input_mux alc861vd_hp_capture_source = {
15558 .num_items = 2,
15559 .items = {
15560 { "Front Mic", 0x0 },
15561 { "ATAPI Mic", 0x1 },
15562 },
15563};
15564
f32610ed
JS
15565/*
15566 * 2ch mode
15567 */
15568static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15569 { 2, NULL }
15570};
15571
15572/*
15573 * 6ch mode
15574 */
15575static struct hda_verb alc861vd_6stack_ch6_init[] = {
15576 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15577 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15578 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15579 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15580 { } /* end */
15581};
15582
15583/*
15584 * 8ch mode
15585 */
15586static struct hda_verb alc861vd_6stack_ch8_init[] = {
15587 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15588 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15589 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15591 { } /* end */
15592};
15593
15594static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15595 { 6, alc861vd_6stack_ch6_init },
15596 { 8, alc861vd_6stack_ch8_init },
15597};
15598
15599static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15600 {
15601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15602 .name = "Channel Mode",
15603 .info = alc_ch_mode_info,
15604 .get = alc_ch_mode_get,
15605 .put = alc_ch_mode_put,
15606 },
15607 { } /* end */
15608};
15609
f32610ed
JS
15610/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15611 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15612 */
15613static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15614 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15615 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15616
15617 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15618 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15619
15620 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15621 HDA_OUTPUT),
15622 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15623 HDA_OUTPUT),
15624 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15625 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15626
15627 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15628 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15629
15630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15631
15632 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15634 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15635
15636 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15637 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15638 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15639
15640 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15641 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15642
15643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15645
f32610ed
JS
15646 { } /* end */
15647};
15648
15649static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15650 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15651 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15652
15653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15654
15655 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15658
15659 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15660 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15661 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15662
15663 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15664 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15665
15666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15668
f32610ed
JS
15669 { } /* end */
15670};
15671
bdd148a3
KY
15672static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15673 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15674 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15675 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15676
15677 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15678
15679 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15682
15683 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15684 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15685 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15686
15687 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15688 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15689
15690 { } /* end */
15691};
15692
b419f346
TD
15693/* Pin assignment: Speaker=0x14, HP = 0x15,
15694 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
15695 */
15696static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
15697 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15698 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
15699 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15700 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
15701 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
15702 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15703 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15704 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
15705 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15706 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
15707 { } /* end */
15708};
15709
d1a991a6
KY
15710/* Pin assignment: Speaker=0x14, Line-out = 0x15,
15711 * Front Mic=0x18, ATAPI Mic = 0x19,
15712 */
15713static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
15714 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15715 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15716 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15717 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15718 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15719 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15720 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15721 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 15722
d1a991a6
KY
15723 { } /* end */
15724};
15725
f32610ed
JS
15726/*
15727 * generic initialization of ADC, input mixers and output mixers
15728 */
15729static struct hda_verb alc861vd_volume_init_verbs[] = {
15730 /*
15731 * Unmute ADC0 and set the default input to mic-in
15732 */
15733 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15734 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15735
15736 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
15737 * the analog-loopback mixer widget
15738 */
15739 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15743 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15744 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
15745
15746 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
15747 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 15750 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
15751
15752 /*
15753 * Set up output mixers (0x02 - 0x05)
15754 */
15755 /* set vol=0 to output mixers */
15756 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15757 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15758 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15759 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15760
15761 /* set up input amps for analog loopback */
15762 /* Amp Indices: DAC = 0, mixer = 1 */
15763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15771
15772 { }
15773};
15774
15775/*
15776 * 3-stack pin configuration:
15777 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15778 */
15779static struct hda_verb alc861vd_3stack_init_verbs[] = {
15780 /*
15781 * Set pin mode and muting
15782 */
15783 /* set front pin widgets 0x14 for output */
15784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15786 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15787
15788 /* Mic (rear) pin: input vref at 80% */
15789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15791 /* Front Mic pin: input vref at 80% */
15792 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15793 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15794 /* Line In pin: input */
15795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15796 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15797 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15798 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15799 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15800 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15801 /* CD pin widget for input */
15802 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15803
15804 { }
15805};
15806
15807/*
15808 * 6-stack pin configuration:
15809 */
15810static struct hda_verb alc861vd_6stack_init_verbs[] = {
15811 /*
15812 * Set pin mode and muting
15813 */
15814 /* set front pin widgets 0x14 for output */
15815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15816 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15818
15819 /* Rear Pin: output 1 (0x0d) */
15820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15823 /* CLFE Pin: output 2 (0x0e) */
15824 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15826 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15827 /* Side Pin: output 3 (0x0f) */
15828 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15829 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15830 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15831
15832 /* Mic (rear) pin: input vref at 80% */
15833 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15835 /* Front Mic pin: input vref at 80% */
15836 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15838 /* Line In pin: input */
15839 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15841 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15842 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15843 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15844 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15845 /* CD pin widget for input */
15846 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15847
15848 { }
15849};
15850
bdd148a3
KY
15851static struct hda_verb alc861vd_eapd_verbs[] = {
15852 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15853 { }
15854};
15855
f9423e7a
KY
15856static struct hda_verb alc660vd_eapd_verbs[] = {
15857 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15858 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15859 { }
15860};
15861
bdd148a3
KY
15862static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15865 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15866 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 15867 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
15868 {}
15869};
15870
bdd148a3
KY
15871static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15872{
15873 unsigned int present;
15874 unsigned char bits;
15875
864f92be 15876 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 15877 bits = present ? HDA_AMP_MUTE : 0;
864f92be 15878
47fd830a
TI
15879 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15880 HDA_AMP_MUTE, bits);
bdd148a3
KY
15881}
15882
4f5d1706 15883static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 15884{
a9fd4f3f 15885 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
15886 spec->autocfg.hp_pins[0] = 0x1b;
15887 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
15888}
15889
15890static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15891{
a9fd4f3f 15892 alc_automute_amp(codec);
bdd148a3
KY
15893 alc861vd_lenovo_mic_automute(codec);
15894}
15895
15896static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15897 unsigned int res)
15898{
15899 switch (res >> 26) {
bdd148a3
KY
15900 case ALC880_MIC_EVENT:
15901 alc861vd_lenovo_mic_automute(codec);
15902 break;
a9fd4f3f
TI
15903 default:
15904 alc_automute_amp_unsol_event(codec, res);
15905 break;
bdd148a3
KY
15906 }
15907}
15908
272a527c
KY
15909static struct hda_verb alc861vd_dallas_verbs[] = {
15910 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15911 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15912 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15913 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15914
15915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15916 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15917 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15919 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15921 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15922 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 15923
272a527c
KY
15924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15926 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15927 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15928 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15929 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15930 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15931 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15932
15933 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15934 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15935 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15936 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15937 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15939 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15940 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15941
15942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15944 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15946
15947 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 15948 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
15949 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15950
15951 { } /* end */
15952};
15953
15954/* toggle speaker-output according to the hp-jack state */
4f5d1706 15955static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 15956{
a9fd4f3f 15957 struct alc_spec *spec = codec->spec;
272a527c 15958
a9fd4f3f
TI
15959 spec->autocfg.hp_pins[0] = 0x15;
15960 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
15961}
15962
cb53c626
TI
15963#ifdef CONFIG_SND_HDA_POWER_SAVE
15964#define alc861vd_loopbacks alc880_loopbacks
15965#endif
15966
def319f9 15967/* pcm configuration: identical with ALC880 */
f32610ed
JS
15968#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15969#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15970#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15971#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15972
15973/*
15974 * configuration and preset
15975 */
15976static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15977 [ALC660VD_3ST] = "3stack-660",
983f8ae4 15978 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 15979 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
15980 [ALC861VD_3ST] = "3stack",
15981 [ALC861VD_3ST_DIG] = "3stack-digout",
15982 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 15983 [ALC861VD_LENOVO] = "lenovo",
272a527c 15984 [ALC861VD_DALLAS] = "dallas",
983f8ae4 15985 [ALC861VD_HP] = "hp",
f32610ed
JS
15986 [ALC861VD_AUTO] = "auto",
15987};
15988
15989static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
15990 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15991 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 15992 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 15993 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 15994 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 15995 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 15996 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 15997 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 15998 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 15999 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16000 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16001 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16002 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16003 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16004 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16005 {}
16006};
16007
16008static struct alc_config_preset alc861vd_presets[] = {
16009 [ALC660VD_3ST] = {
16010 .mixers = { alc861vd_3st_mixer },
16011 .init_verbs = { alc861vd_volume_init_verbs,
16012 alc861vd_3stack_init_verbs },
16013 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16014 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16015 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16016 .channel_mode = alc861vd_3stack_2ch_modes,
16017 .input_mux = &alc861vd_capture_source,
16018 },
6963f84c
MC
16019 [ALC660VD_3ST_DIG] = {
16020 .mixers = { alc861vd_3st_mixer },
16021 .init_verbs = { alc861vd_volume_init_verbs,
16022 alc861vd_3stack_init_verbs },
16023 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16024 .dac_nids = alc660vd_dac_nids,
16025 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16026 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16027 .channel_mode = alc861vd_3stack_2ch_modes,
16028 .input_mux = &alc861vd_capture_source,
16029 },
f32610ed
JS
16030 [ALC861VD_3ST] = {
16031 .mixers = { alc861vd_3st_mixer },
16032 .init_verbs = { alc861vd_volume_init_verbs,
16033 alc861vd_3stack_init_verbs },
16034 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16035 .dac_nids = alc861vd_dac_nids,
16036 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16037 .channel_mode = alc861vd_3stack_2ch_modes,
16038 .input_mux = &alc861vd_capture_source,
16039 },
16040 [ALC861VD_3ST_DIG] = {
16041 .mixers = { alc861vd_3st_mixer },
16042 .init_verbs = { alc861vd_volume_init_verbs,
16043 alc861vd_3stack_init_verbs },
16044 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16045 .dac_nids = alc861vd_dac_nids,
16046 .dig_out_nid = ALC861VD_DIGOUT_NID,
16047 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16048 .channel_mode = alc861vd_3stack_2ch_modes,
16049 .input_mux = &alc861vd_capture_source,
16050 },
16051 [ALC861VD_6ST_DIG] = {
16052 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16053 .init_verbs = { alc861vd_volume_init_verbs,
16054 alc861vd_6stack_init_verbs },
16055 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16056 .dac_nids = alc861vd_dac_nids,
16057 .dig_out_nid = ALC861VD_DIGOUT_NID,
16058 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16059 .channel_mode = alc861vd_6stack_modes,
16060 .input_mux = &alc861vd_capture_source,
16061 },
bdd148a3
KY
16062 [ALC861VD_LENOVO] = {
16063 .mixers = { alc861vd_lenovo_mixer },
16064 .init_verbs = { alc861vd_volume_init_verbs,
16065 alc861vd_3stack_init_verbs,
16066 alc861vd_eapd_verbs,
16067 alc861vd_lenovo_unsol_verbs },
16068 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16069 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16070 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16071 .channel_mode = alc861vd_3stack_2ch_modes,
16072 .input_mux = &alc861vd_capture_source,
16073 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16074 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16075 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16076 },
272a527c
KY
16077 [ALC861VD_DALLAS] = {
16078 .mixers = { alc861vd_dallas_mixer },
16079 .init_verbs = { alc861vd_dallas_verbs },
16080 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16081 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16082 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16083 .channel_mode = alc861vd_3stack_2ch_modes,
16084 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16085 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16086 .setup = alc861vd_dallas_setup,
16087 .init_hook = alc_automute_amp,
d1a991a6
KY
16088 },
16089 [ALC861VD_HP] = {
16090 .mixers = { alc861vd_hp_mixer },
16091 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16092 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16093 .dac_nids = alc861vd_dac_nids,
d1a991a6 16094 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16095 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16096 .channel_mode = alc861vd_3stack_2ch_modes,
16097 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16098 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16099 .setup = alc861vd_dallas_setup,
16100 .init_hook = alc_automute_amp,
ea1fb29a 16101 },
13c94744
TI
16102 [ALC660VD_ASUS_V1S] = {
16103 .mixers = { alc861vd_lenovo_mixer },
16104 .init_verbs = { alc861vd_volume_init_verbs,
16105 alc861vd_3stack_init_verbs,
16106 alc861vd_eapd_verbs,
16107 alc861vd_lenovo_unsol_verbs },
16108 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16109 .dac_nids = alc660vd_dac_nids,
16110 .dig_out_nid = ALC861VD_DIGOUT_NID,
16111 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16112 .channel_mode = alc861vd_3stack_2ch_modes,
16113 .input_mux = &alc861vd_capture_source,
16114 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16115 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16116 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16117 },
f32610ed
JS
16118};
16119
16120/*
16121 * BIOS auto configuration
16122 */
05f5f477
TI
16123static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16124 const struct auto_pin_cfg *cfg)
16125{
6227cdce 16126 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16127}
16128
16129
f32610ed
JS
16130static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16131 hda_nid_t nid, int pin_type, int dac_idx)
16132{
f6c7e546 16133 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16134}
16135
16136static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16137{
16138 struct alc_spec *spec = codec->spec;
16139 int i;
16140
16141 for (i = 0; i <= HDA_SIDE; i++) {
16142 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16143 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16144 if (nid)
16145 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16146 pin_type, i);
f32610ed
JS
16147 }
16148}
16149
16150
16151static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16152{
16153 struct alc_spec *spec = codec->spec;
16154 hda_nid_t pin;
16155
16156 pin = spec->autocfg.hp_pins[0];
def319f9 16157 if (pin) /* connect to front and use dac 0 */
f32610ed 16158 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16159 pin = spec->autocfg.speaker_pins[0];
16160 if (pin)
16161 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16162}
16163
f32610ed
JS
16164#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16165
16166static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16167{
16168 struct alc_spec *spec = codec->spec;
16169 int i;
16170
16171 for (i = 0; i < AUTO_PIN_LAST; i++) {
16172 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16173 if (alc_is_input_pin(codec, nid)) {
23f0c048 16174 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16175 if (nid != ALC861VD_PIN_CD_NID &&
16176 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16177 snd_hda_codec_write(codec, nid, 0,
16178 AC_VERB_SET_AMP_GAIN_MUTE,
16179 AMP_OUT_MUTE);
16180 }
16181 }
16182}
16183
f511b01c
TI
16184#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16185
f32610ed
JS
16186#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16187#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16188
16189/* add playback controls from the parsed DAC table */
16190/* Based on ALC880 version. But ALC861VD has separate,
16191 * different NIDs for mute/unmute switch and volume control */
16192static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16193 const struct auto_pin_cfg *cfg)
16194{
f32610ed
JS
16195 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16196 hda_nid_t nid_v, nid_s;
16197 int i, err;
16198
16199 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16200 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16201 continue;
16202 nid_v = alc861vd_idx_to_mixer_vol(
16203 alc880_dac_to_idx(
16204 spec->multiout.dac_nids[i]));
16205 nid_s = alc861vd_idx_to_mixer_switch(
16206 alc880_dac_to_idx(
16207 spec->multiout.dac_nids[i]));
16208
16209 if (i == 2) {
16210 /* Center/LFE */
0afe5f89
TI
16211 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16212 "Center",
f12ab1e0
TI
16213 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16214 HDA_OUTPUT));
16215 if (err < 0)
f32610ed 16216 return err;
0afe5f89
TI
16217 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16218 "LFE",
f12ab1e0
TI
16219 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16220 HDA_OUTPUT));
16221 if (err < 0)
f32610ed 16222 return err;
0afe5f89
TI
16223 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16224 "Center",
f12ab1e0
TI
16225 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16226 HDA_INPUT));
16227 if (err < 0)
f32610ed 16228 return err;
0afe5f89
TI
16229 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16230 "LFE",
f12ab1e0
TI
16231 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16232 HDA_INPUT));
16233 if (err < 0)
f32610ed
JS
16234 return err;
16235 } else {
a4fcd491
TI
16236 const char *pfx;
16237 if (cfg->line_outs == 1 &&
16238 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16239 if (!cfg->hp_pins)
16240 pfx = "Speaker";
16241 else
16242 pfx = "PCM";
16243 } else
16244 pfx = chname[i];
0afe5f89 16245 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16246 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16247 HDA_OUTPUT));
16248 if (err < 0)
f32610ed 16249 return err;
a4fcd491
TI
16250 if (cfg->line_outs == 1 &&
16251 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16252 pfx = "Speaker";
0afe5f89 16253 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16254 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16255 HDA_INPUT));
16256 if (err < 0)
f32610ed
JS
16257 return err;
16258 }
16259 }
16260 return 0;
16261}
16262
16263/* add playback controls for speaker and HP outputs */
16264/* Based on ALC880 version. But ALC861VD has separate,
16265 * different NIDs for mute/unmute switch and volume control */
16266static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16267 hda_nid_t pin, const char *pfx)
16268{
16269 hda_nid_t nid_v, nid_s;
16270 int err;
f32610ed 16271
f12ab1e0 16272 if (!pin)
f32610ed
JS
16273 return 0;
16274
16275 if (alc880_is_fixed_pin(pin)) {
16276 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16277 /* specify the DAC as the extra output */
f12ab1e0 16278 if (!spec->multiout.hp_nid)
f32610ed
JS
16279 spec->multiout.hp_nid = nid_v;
16280 else
16281 spec->multiout.extra_out_nid[0] = nid_v;
16282 /* control HP volume/switch on the output mixer amp */
16283 nid_v = alc861vd_idx_to_mixer_vol(
16284 alc880_fixed_pin_idx(pin));
16285 nid_s = alc861vd_idx_to_mixer_switch(
16286 alc880_fixed_pin_idx(pin));
16287
0afe5f89 16288 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16289 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16290 if (err < 0)
f32610ed 16291 return err;
0afe5f89 16292 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16293 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16294 if (err < 0)
f32610ed
JS
16295 return err;
16296 } else if (alc880_is_multi_pin(pin)) {
16297 /* set manual connection */
16298 /* we have only a switch on HP-out PIN */
0afe5f89 16299 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16300 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16301 if (err < 0)
f32610ed
JS
16302 return err;
16303 }
16304 return 0;
16305}
16306
16307/* parse the BIOS configuration and set up the alc_spec
16308 * return 1 if successful, 0 if the proper config is not found,
16309 * or a negative error code
16310 * Based on ALC880 version - had to change it to override
16311 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16312static int alc861vd_parse_auto_config(struct hda_codec *codec)
16313{
16314 struct alc_spec *spec = codec->spec;
16315 int err;
16316 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16317
f12ab1e0
TI
16318 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16319 alc861vd_ignore);
16320 if (err < 0)
f32610ed 16321 return err;
f12ab1e0 16322 if (!spec->autocfg.line_outs)
f32610ed
JS
16323 return 0; /* can't find valid BIOS pin config */
16324
f12ab1e0
TI
16325 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16326 if (err < 0)
16327 return err;
16328 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16329 if (err < 0)
16330 return err;
16331 err = alc861vd_auto_create_extra_out(spec,
16332 spec->autocfg.speaker_pins[0],
16333 "Speaker");
16334 if (err < 0)
16335 return err;
16336 err = alc861vd_auto_create_extra_out(spec,
16337 spec->autocfg.hp_pins[0],
16338 "Headphone");
16339 if (err < 0)
16340 return err;
05f5f477 16341 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16342 if (err < 0)
f32610ed
JS
16343 return err;
16344
16345 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16346
0852d7a6 16347 if (spec->autocfg.dig_outs)
f32610ed
JS
16348 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16349
603c4019 16350 if (spec->kctls.list)
d88897ea 16351 add_mixer(spec, spec->kctls.list);
f32610ed 16352
d88897ea 16353 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16354
16355 spec->num_mux_defs = 1;
61b9b9b1 16356 spec->input_mux = &spec->private_imux[0];
f32610ed 16357
776e184e
TI
16358 err = alc_auto_add_mic_boost(codec);
16359 if (err < 0)
16360 return err;
16361
6227cdce 16362 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16363
f32610ed
JS
16364 return 1;
16365}
16366
16367/* additional initialization for auto-configuration model */
16368static void alc861vd_auto_init(struct hda_codec *codec)
16369{
f6c7e546 16370 struct alc_spec *spec = codec->spec;
f32610ed
JS
16371 alc861vd_auto_init_multi_out(codec);
16372 alc861vd_auto_init_hp_out(codec);
16373 alc861vd_auto_init_analog_input(codec);
f511b01c 16374 alc861vd_auto_init_input_src(codec);
f6c7e546 16375 if (spec->unsol_event)
7fb0d78f 16376 alc_inithook(codec);
f32610ed
JS
16377}
16378
f8f25ba3
TI
16379enum {
16380 ALC660VD_FIX_ASUS_GPIO1
16381};
16382
16383/* reset GPIO1 */
16384static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16385 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16386 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16387 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16388 { }
16389};
16390
16391static const struct alc_fixup alc861vd_fixups[] = {
16392 [ALC660VD_FIX_ASUS_GPIO1] = {
16393 .verbs = alc660vd_fix_asus_gpio1_verbs,
16394 },
16395};
16396
16397static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16398 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16399 {}
16400};
16401
f32610ed
JS
16402static int patch_alc861vd(struct hda_codec *codec)
16403{
16404 struct alc_spec *spec;
16405 int err, board_config;
16406
16407 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16408 if (spec == NULL)
16409 return -ENOMEM;
16410
16411 codec->spec = spec;
16412
16413 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16414 alc861vd_models,
16415 alc861vd_cfg_tbl);
16416
16417 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16418 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16419 codec->chip_name);
f32610ed
JS
16420 board_config = ALC861VD_AUTO;
16421 }
16422
f8f25ba3
TI
16423 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
16424
f32610ed
JS
16425 if (board_config == ALC861VD_AUTO) {
16426 /* automatic parse from the BIOS config */
16427 err = alc861vd_parse_auto_config(codec);
16428 if (err < 0) {
16429 alc_free(codec);
16430 return err;
f12ab1e0 16431 } else if (!err) {
f32610ed
JS
16432 printk(KERN_INFO
16433 "hda_codec: Cannot set up configuration "
16434 "from BIOS. Using base mode...\n");
16435 board_config = ALC861VD_3ST;
16436 }
16437 }
16438
680cd536
KK
16439 err = snd_hda_attach_beep_device(codec, 0x23);
16440 if (err < 0) {
16441 alc_free(codec);
16442 return err;
16443 }
16444
f32610ed 16445 if (board_config != ALC861VD_AUTO)
e9c364c0 16446 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16447
2f893286 16448 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16449 /* always turn on EAPD */
d88897ea 16450 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16451 }
16452
f32610ed
JS
16453 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16454 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16455
f32610ed
JS
16456 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16457 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16458
dd704698
TI
16459 if (!spec->adc_nids) {
16460 spec->adc_nids = alc861vd_adc_nids;
16461 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16462 }
16463 if (!spec->capsrc_nids)
16464 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16465
b59bdf3b 16466 set_capture_mixer(codec);
45bdd1c1 16467 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16468
2134ea4f
TI
16469 spec->vmaster_nid = 0x02;
16470
f32610ed
JS
16471 codec->patch_ops = alc_patch_ops;
16472
16473 if (board_config == ALC861VD_AUTO)
16474 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16475#ifdef CONFIG_SND_HDA_POWER_SAVE
16476 if (!spec->loopback.amplist)
16477 spec->loopback.amplist = alc861vd_loopbacks;
16478#endif
f32610ed
JS
16479
16480 return 0;
16481}
16482
bc9f98a9
KY
16483/*
16484 * ALC662 support
16485 *
16486 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16487 * configuration. Each pin widget can choose any input DACs and a mixer.
16488 * Each ADC is connected from a mixer of all inputs. This makes possible
16489 * 6-channel independent captures.
16490 *
16491 * In addition, an independent DAC for the multi-playback (not used in this
16492 * driver yet).
16493 */
16494#define ALC662_DIGOUT_NID 0x06
16495#define ALC662_DIGIN_NID 0x0a
16496
16497static hda_nid_t alc662_dac_nids[4] = {
16498 /* front, rear, clfe, rear_surr */
16499 0x02, 0x03, 0x04
16500};
16501
622e84cd
KY
16502static hda_nid_t alc272_dac_nids[2] = {
16503 0x02, 0x03
16504};
16505
b59bdf3b 16506static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16507 /* ADC1-2 */
b59bdf3b 16508 0x09, 0x08
bc9f98a9 16509};
e1406348 16510
622e84cd
KY
16511static hda_nid_t alc272_adc_nids[1] = {
16512 /* ADC1-2 */
16513 0x08,
16514};
16515
b59bdf3b 16516static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16517static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16518
e1406348 16519
bc9f98a9
KY
16520/* input MUX */
16521/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16522static struct hda_input_mux alc662_capture_source = {
16523 .num_items = 4,
16524 .items = {
16525 { "Mic", 0x0 },
16526 { "Front Mic", 0x1 },
16527 { "Line", 0x2 },
16528 { "CD", 0x4 },
16529 },
16530};
16531
16532static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16533 .num_items = 2,
16534 .items = {
16535 { "Mic", 0x1 },
16536 { "Line", 0x2 },
16537 },
16538};
291702f0 16539
6dda9f4a
KY
16540static struct hda_input_mux alc663_capture_source = {
16541 .num_items = 3,
16542 .items = {
16543 { "Mic", 0x0 },
16544 { "Front Mic", 0x1 },
16545 { "Line", 0x2 },
16546 },
16547};
16548
4f5d1706 16549#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16550static struct hda_input_mux alc272_nc10_capture_source = {
16551 .num_items = 16,
16552 .items = {
16553 { "Autoselect Mic", 0x0 },
16554 { "Internal Mic", 0x1 },
16555 { "In-0x02", 0x2 },
16556 { "In-0x03", 0x3 },
16557 { "In-0x04", 0x4 },
16558 { "In-0x05", 0x5 },
16559 { "In-0x06", 0x6 },
16560 { "In-0x07", 0x7 },
16561 { "In-0x08", 0x8 },
16562 { "In-0x09", 0x9 },
16563 { "In-0x0a", 0x0a },
16564 { "In-0x0b", 0x0b },
16565 { "In-0x0c", 0x0c },
16566 { "In-0x0d", 0x0d },
16567 { "In-0x0e", 0x0e },
16568 { "In-0x0f", 0x0f },
16569 },
16570};
16571#endif
16572
bc9f98a9
KY
16573/*
16574 * 2ch mode
16575 */
16576static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16577 { 2, NULL }
16578};
16579
16580/*
16581 * 2ch mode
16582 */
16583static struct hda_verb alc662_3ST_ch2_init[] = {
16584 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16585 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16586 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16587 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16588 { } /* end */
16589};
16590
16591/*
16592 * 6ch mode
16593 */
16594static struct hda_verb alc662_3ST_ch6_init[] = {
16595 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16596 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16597 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16598 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16599 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16600 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16601 { } /* end */
16602};
16603
16604static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16605 { 2, alc662_3ST_ch2_init },
16606 { 6, alc662_3ST_ch6_init },
16607};
16608
16609/*
16610 * 2ch mode
16611 */
16612static struct hda_verb alc662_sixstack_ch6_init[] = {
16613 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16614 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16615 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16616 { } /* end */
16617};
16618
16619/*
16620 * 6ch mode
16621 */
16622static struct hda_verb alc662_sixstack_ch8_init[] = {
16623 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16624 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16625 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16626 { } /* end */
16627};
16628
16629static struct hda_channel_mode alc662_5stack_modes[2] = {
16630 { 2, alc662_sixstack_ch6_init },
16631 { 6, alc662_sixstack_ch8_init },
16632};
16633
16634/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16635 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16636 */
16637
16638static struct snd_kcontrol_new alc662_base_mixer[] = {
16639 /* output mixer control */
16640 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16641 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16642 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16643 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16644 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16645 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16646 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16647 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16649
16650 /*Input mixer control */
16651 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16652 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16653 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16654 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16655 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16656 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16659 { } /* end */
16660};
16661
16662static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16664 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
16665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16672 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16673 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16674 { } /* end */
16675};
16676
16677static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16678 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16679 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16680 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 16681 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16682 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16683 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16684 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16685 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16686 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16687 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16688 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16694 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16695 { } /* end */
16696};
16697
16698static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16699 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16700 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
16701 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16702 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
16703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16708 { } /* end */
16709};
16710
291702f0 16711static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
16712 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16713 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
16714
16715 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
16716 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16717 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16718
16719 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16720 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16721 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16722 { } /* end */
16723};
16724
8c427226 16725static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
16726 ALC262_HIPPO_MASTER_SWITCH,
16727 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 16728 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
16729 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16730 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
16731 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
16732 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16733 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16736 { } /* end */
16737};
16738
f1d4e28b
KY
16739static struct hda_bind_ctls alc663_asus_bind_master_vol = {
16740 .ops = &snd_hda_bind_vol,
16741 .values = {
16742 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16743 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
16744 0
16745 },
16746};
16747
16748static struct hda_bind_ctls alc663_asus_one_bind_switch = {
16749 .ops = &snd_hda_bind_sw,
16750 .values = {
16751 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16752 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16753 0
16754 },
16755};
16756
6dda9f4a 16757static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
16758 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16759 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16762 { } /* end */
16763};
16764
16765static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16766 .ops = &snd_hda_bind_sw,
16767 .values = {
16768 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16769 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16770 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16771 0
16772 },
16773};
16774
16775static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16776 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16777 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16779 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16780 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16781 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16782
16783 { } /* end */
16784};
16785
16786static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16787 .ops = &snd_hda_bind_sw,
16788 .values = {
16789 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16790 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16791 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16792 0
16793 },
16794};
16795
16796static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16797 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16798 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16799 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16800 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16801 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16802 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16803 { } /* end */
16804};
16805
16806static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
16807 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16808 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
16809 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16811 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16812 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16813 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16814 { } /* end */
16815};
16816
16817static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16818 .ops = &snd_hda_bind_vol,
16819 .values = {
16820 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16821 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16822 0
16823 },
16824};
16825
16826static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16827 .ops = &snd_hda_bind_sw,
16828 .values = {
16829 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16830 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16831 0
16832 },
16833};
16834
16835static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16836 HDA_BIND_VOL("Master Playback Volume",
16837 &alc663_asus_two_bind_master_vol),
16838 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
16840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
16843 { } /* end */
16844};
16845
16846static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16847 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16848 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16849 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16850 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
16853 { } /* end */
16854};
16855
16856static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16857 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16858 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16859 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16860 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16862
16863 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16864 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16865 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16866 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16867 { } /* end */
16868};
16869
16870static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16871 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16872 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16873 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16874
16875 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16876 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16877 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16878 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16879 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16880 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16881 { } /* end */
16882};
16883
ebb83eeb
KY
16884static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
16885 .ops = &snd_hda_bind_sw,
16886 .values = {
16887 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16888 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16889 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16890 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16891 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16892 0
16893 },
16894};
16895
16896static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
16897 .ops = &snd_hda_bind_sw,
16898 .values = {
16899 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16900 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16901 0
16902 },
16903};
16904
16905static struct snd_kcontrol_new alc663_mode7_mixer[] = {
16906 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16907 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16908 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16909 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16910 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16911 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16912 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16913 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16914 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16915 { } /* end */
16916};
16917
16918static struct snd_kcontrol_new alc663_mode8_mixer[] = {
16919 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16920 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16921 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16922 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16923 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16925 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16926 { } /* end */
16927};
16928
16929
bc9f98a9
KY
16930static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16931 {
16932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16933 .name = "Channel Mode",
16934 .info = alc_ch_mode_info,
16935 .get = alc_ch_mode_get,
16936 .put = alc_ch_mode_put,
16937 },
16938 { } /* end */
16939};
16940
16941static struct hda_verb alc662_init_verbs[] = {
16942 /* ADC: mute amp left and right */
16943 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16944 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 16945
b60dd394
KY
16946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16948 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16949 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16951 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
16952
16953 /* Front Pin: output 0 (0x0c) */
16954 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16955 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16956
16957 /* Rear Pin: output 1 (0x0d) */
16958 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16959 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16960
16961 /* CLFE Pin: output 2 (0x0e) */
16962 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16963 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16964
16965 /* Mic (rear) pin: input vref at 80% */
16966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16967 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16968 /* Front Mic pin: input vref at 80% */
16969 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16970 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16971 /* Line In pin: input */
16972 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16973 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16974 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16975 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16976 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16977 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16978 /* CD pin widget for input */
16979 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16980
16981 /* FIXME: use matrix-type input source selection */
16982 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16983 /* Input mixer */
16984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 16985 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
16986
16987 /* always trun on EAPD */
16988 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16989 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16990
bc9f98a9
KY
16991 { }
16992};
16993
cec27c89
KY
16994static struct hda_verb alc663_init_verbs[] = {
16995 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16996 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16997 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16998 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17001 { }
17002};
17003
17004static struct hda_verb alc272_init_verbs[] = {
17005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17007 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17009 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17010 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17011 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17012 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17013 { }
17014};
17015
bc9f98a9
KY
17016static struct hda_verb alc662_sue_init_verbs[] = {
17017 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17019 {}
17020};
17021
17022static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17023 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17024 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17025 {}
bc9f98a9
KY
17026};
17027
8c427226
KY
17028/* Set Unsolicited Event*/
17029static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17030 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17031 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17032 {}
17033};
17034
6dda9f4a 17035static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17037 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17038 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17039 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17040 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17044 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17045 {}
17046};
17047
17048static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17049 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17050 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17051 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17055 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17056 {}
17057};
17058
17059static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17060 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17061 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17063 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17066 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17067 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17068 {}
17069};
6dda9f4a 17070
f1d4e28b
KY
17071static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17073 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17074 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17077 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17078 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17079 {}
17080};
6dda9f4a 17081
f1d4e28b
KY
17082static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17083 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17084 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17085 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17086 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17089 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17092 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17093 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17094 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17095 {}
17096};
17097
17098static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17099 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17101 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17102 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17103 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17104 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17105 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17106 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17109 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17110 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17111 {}
17112};
17113
17114static struct hda_verb alc663_g71v_init_verbs[] = {
17115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17116 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17117 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17118
17119 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17120 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17121 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17122
17123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17124 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17125 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17126 {}
17127};
17128
17129static struct hda_verb alc663_g50v_init_verbs[] = {
17130 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17131 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17132 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17133
17134 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17135 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17136 {}
17137};
17138
f1d4e28b
KY
17139static struct hda_verb alc662_ecs_init_verbs[] = {
17140 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17142 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17143 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17144 {}
17145};
17146
622e84cd
KY
17147static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17148 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17149 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17150 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17151 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17152 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17153 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17154 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17159 {}
17160};
17161
17162static struct hda_verb alc272_dell_init_verbs[] = {
17163 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17164 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17165 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17166 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17167 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17168 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17169 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17170 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17171 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17172 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17173 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17174 {}
17175};
17176
ebb83eeb
KY
17177static struct hda_verb alc663_mode7_init_verbs[] = {
17178 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17179 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17180 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17181 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17184 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17185 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17186 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17187 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17188 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17189 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17190 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17191 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17192 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17193 {}
17194};
17195
17196static struct hda_verb alc663_mode8_init_verbs[] = {
17197 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17198 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17199 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17200 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17201 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17202 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17203 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17204 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17205 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17206 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17207 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17208 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17209 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17210 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17211 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17212 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17213 {}
17214};
17215
f1d4e28b
KY
17216static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17217 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17218 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17219 { } /* end */
17220};
17221
622e84cd
KY
17222static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17223 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17224 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17225 { } /* end */
17226};
17227
bc9f98a9
KY
17228static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17229{
17230 unsigned int present;
f12ab1e0 17231 unsigned char bits;
bc9f98a9 17232
864f92be 17233 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17234 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17235
47fd830a
TI
17236 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17237 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17238}
17239
17240static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17241{
17242 unsigned int present;
f12ab1e0 17243 unsigned char bits;
bc9f98a9 17244
864f92be 17245 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17246 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17247
47fd830a
TI
17248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17249 HDA_AMP_MUTE, bits);
17250 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17251 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17252}
17253
17254static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17255 unsigned int res)
17256{
17257 if ((res >> 26) == ALC880_HP_EVENT)
17258 alc662_lenovo_101e_all_automute(codec);
17259 if ((res >> 26) == ALC880_FRONT_EVENT)
17260 alc662_lenovo_101e_ispeaker_automute(codec);
17261}
17262
291702f0
KY
17263/* unsolicited event for HP jack sensing */
17264static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17265 unsigned int res)
17266{
291702f0 17267 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17268 alc_mic_automute(codec);
42171c17
TI
17269 else
17270 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17271}
17272
4f5d1706
TI
17273static void alc662_eeepc_setup(struct hda_codec *codec)
17274{
17275 struct alc_spec *spec = codec->spec;
17276
17277 alc262_hippo1_setup(codec);
17278 spec->ext_mic.pin = 0x18;
17279 spec->ext_mic.mux_idx = 0;
17280 spec->int_mic.pin = 0x19;
17281 spec->int_mic.mux_idx = 1;
17282 spec->auto_mic = 1;
17283}
17284
291702f0
KY
17285static void alc662_eeepc_inithook(struct hda_codec *codec)
17286{
4f5d1706
TI
17287 alc262_hippo_automute(codec);
17288 alc_mic_automute(codec);
291702f0
KY
17289}
17290
4f5d1706 17291static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17292{
42171c17
TI
17293 struct alc_spec *spec = codec->spec;
17294
17295 spec->autocfg.hp_pins[0] = 0x14;
17296 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17297}
17298
4f5d1706
TI
17299#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17300
6dda9f4a
KY
17301static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17302{
17303 unsigned int present;
17304 unsigned char bits;
17305
864f92be 17306 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17307 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17308 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17309 HDA_AMP_MUTE, bits);
f1d4e28b 17310 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17311 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17312}
17313
17314static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17315{
17316 unsigned int present;
17317 unsigned char bits;
17318
864f92be 17319 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17320 bits = present ? HDA_AMP_MUTE : 0;
17321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17322 HDA_AMP_MUTE, bits);
f1d4e28b 17323 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17324 HDA_AMP_MUTE, bits);
f1d4e28b 17325 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17326 HDA_AMP_MUTE, bits);
f1d4e28b 17327 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17328 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17329}
17330
17331static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17332{
17333 unsigned int present;
17334 unsigned char bits;
17335
864f92be 17336 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17337 bits = present ? HDA_AMP_MUTE : 0;
17338 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17339 HDA_AMP_MUTE, bits);
f1d4e28b 17340 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17341 HDA_AMP_MUTE, bits);
f1d4e28b 17342 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17343 HDA_AMP_MUTE, bits);
f1d4e28b 17344 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17345 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17346}
17347
17348static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17349{
17350 unsigned int present;
17351 unsigned char bits;
17352
864f92be 17353 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17354 bits = present ? 0 : PIN_OUT;
17355 snd_hda_codec_write(codec, 0x14, 0,
17356 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17357}
17358
17359static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17360{
17361 unsigned int present1, present2;
17362
864f92be
WF
17363 present1 = snd_hda_jack_detect(codec, 0x21);
17364 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17365
17366 if (present1 || present2) {
17367 snd_hda_codec_write_cache(codec, 0x14, 0,
17368 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17369 } else {
17370 snd_hda_codec_write_cache(codec, 0x14, 0,
17371 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17372 }
17373}
17374
17375static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17376{
17377 unsigned int present1, present2;
17378
864f92be
WF
17379 present1 = snd_hda_jack_detect(codec, 0x1b);
17380 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17381
17382 if (present1 || present2) {
17383 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17384 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17385 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17386 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17387 } else {
17388 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17389 HDA_AMP_MUTE, 0);
f1d4e28b 17390 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17391 HDA_AMP_MUTE, 0);
f1d4e28b 17392 }
6dda9f4a
KY
17393}
17394
ebb83eeb
KY
17395static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17396{
17397 unsigned int present1, present2;
17398
17399 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17400 AC_VERB_GET_PIN_SENSE, 0)
17401 & AC_PINSENSE_PRESENCE;
17402 present2 = snd_hda_codec_read(codec, 0x21, 0,
17403 AC_VERB_GET_PIN_SENSE, 0)
17404 & AC_PINSENSE_PRESENCE;
17405
17406 if (present1 || present2) {
17407 snd_hda_codec_write_cache(codec, 0x14, 0,
17408 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17409 snd_hda_codec_write_cache(codec, 0x17, 0,
17410 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17411 } else {
17412 snd_hda_codec_write_cache(codec, 0x14, 0,
17413 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17414 snd_hda_codec_write_cache(codec, 0x17, 0,
17415 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17416 }
17417}
17418
17419static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17420{
17421 unsigned int present1, present2;
17422
17423 present1 = snd_hda_codec_read(codec, 0x21, 0,
17424 AC_VERB_GET_PIN_SENSE, 0)
17425 & AC_PINSENSE_PRESENCE;
17426 present2 = snd_hda_codec_read(codec, 0x15, 0,
17427 AC_VERB_GET_PIN_SENSE, 0)
17428 & AC_PINSENSE_PRESENCE;
17429
17430 if (present1 || present2) {
17431 snd_hda_codec_write_cache(codec, 0x14, 0,
17432 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17433 snd_hda_codec_write_cache(codec, 0x17, 0,
17434 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17435 } else {
17436 snd_hda_codec_write_cache(codec, 0x14, 0,
17437 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17438 snd_hda_codec_write_cache(codec, 0x17, 0,
17439 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17440 }
17441}
17442
6dda9f4a
KY
17443static void alc663_m51va_unsol_event(struct hda_codec *codec,
17444 unsigned int res)
17445{
17446 switch (res >> 26) {
17447 case ALC880_HP_EVENT:
17448 alc663_m51va_speaker_automute(codec);
17449 break;
17450 case ALC880_MIC_EVENT:
4f5d1706 17451 alc_mic_automute(codec);
6dda9f4a
KY
17452 break;
17453 }
17454}
17455
4f5d1706
TI
17456static void alc663_m51va_setup(struct hda_codec *codec)
17457{
17458 struct alc_spec *spec = codec->spec;
17459 spec->ext_mic.pin = 0x18;
17460 spec->ext_mic.mux_idx = 0;
17461 spec->int_mic.pin = 0x12;
ebb83eeb 17462 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17463 spec->auto_mic = 1;
17464}
17465
6dda9f4a
KY
17466static void alc663_m51va_inithook(struct hda_codec *codec)
17467{
17468 alc663_m51va_speaker_automute(codec);
4f5d1706 17469 alc_mic_automute(codec);
6dda9f4a
KY
17470}
17471
f1d4e28b 17472/* ***************** Mode1 ******************************/
4f5d1706 17473#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17474
17475static void alc663_mode1_setup(struct hda_codec *codec)
17476{
17477 struct alc_spec *spec = codec->spec;
17478 spec->ext_mic.pin = 0x18;
17479 spec->ext_mic.mux_idx = 0;
17480 spec->int_mic.pin = 0x19;
17481 spec->int_mic.mux_idx = 1;
17482 spec->auto_mic = 1;
17483}
17484
4f5d1706 17485#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17486
f1d4e28b
KY
17487/* ***************** Mode2 ******************************/
17488static void alc662_mode2_unsol_event(struct hda_codec *codec,
17489 unsigned int res)
17490{
17491 switch (res >> 26) {
17492 case ALC880_HP_EVENT:
17493 alc662_f5z_speaker_automute(codec);
17494 break;
17495 case ALC880_MIC_EVENT:
4f5d1706 17496 alc_mic_automute(codec);
f1d4e28b
KY
17497 break;
17498 }
17499}
17500
ebb83eeb 17501#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17502
f1d4e28b
KY
17503static void alc662_mode2_inithook(struct hda_codec *codec)
17504{
17505 alc662_f5z_speaker_automute(codec);
4f5d1706 17506 alc_mic_automute(codec);
f1d4e28b
KY
17507}
17508/* ***************** Mode3 ******************************/
17509static void alc663_mode3_unsol_event(struct hda_codec *codec,
17510 unsigned int res)
17511{
17512 switch (res >> 26) {
17513 case ALC880_HP_EVENT:
17514 alc663_two_hp_m1_speaker_automute(codec);
17515 break;
17516 case ALC880_MIC_EVENT:
4f5d1706 17517 alc_mic_automute(codec);
f1d4e28b
KY
17518 break;
17519 }
17520}
17521
ebb83eeb 17522#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17523
f1d4e28b
KY
17524static void alc663_mode3_inithook(struct hda_codec *codec)
17525{
17526 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17527 alc_mic_automute(codec);
f1d4e28b
KY
17528}
17529/* ***************** Mode4 ******************************/
17530static void alc663_mode4_unsol_event(struct hda_codec *codec,
17531 unsigned int res)
17532{
17533 switch (res >> 26) {
17534 case ALC880_HP_EVENT:
17535 alc663_21jd_two_speaker_automute(codec);
17536 break;
17537 case ALC880_MIC_EVENT:
4f5d1706 17538 alc_mic_automute(codec);
f1d4e28b
KY
17539 break;
17540 }
17541}
17542
ebb83eeb 17543#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17544
f1d4e28b
KY
17545static void alc663_mode4_inithook(struct hda_codec *codec)
17546{
17547 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17548 alc_mic_automute(codec);
f1d4e28b
KY
17549}
17550/* ***************** Mode5 ******************************/
17551static void alc663_mode5_unsol_event(struct hda_codec *codec,
17552 unsigned int res)
17553{
17554 switch (res >> 26) {
17555 case ALC880_HP_EVENT:
17556 alc663_15jd_two_speaker_automute(codec);
17557 break;
17558 case ALC880_MIC_EVENT:
4f5d1706 17559 alc_mic_automute(codec);
f1d4e28b
KY
17560 break;
17561 }
17562}
17563
ebb83eeb 17564#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17565
f1d4e28b
KY
17566static void alc663_mode5_inithook(struct hda_codec *codec)
17567{
17568 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17569 alc_mic_automute(codec);
f1d4e28b
KY
17570}
17571/* ***************** Mode6 ******************************/
17572static void alc663_mode6_unsol_event(struct hda_codec *codec,
17573 unsigned int res)
17574{
17575 switch (res >> 26) {
17576 case ALC880_HP_EVENT:
17577 alc663_two_hp_m2_speaker_automute(codec);
17578 break;
17579 case ALC880_MIC_EVENT:
4f5d1706 17580 alc_mic_automute(codec);
f1d4e28b
KY
17581 break;
17582 }
17583}
17584
ebb83eeb 17585#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17586
f1d4e28b
KY
17587static void alc663_mode6_inithook(struct hda_codec *codec)
17588{
17589 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17590 alc_mic_automute(codec);
f1d4e28b
KY
17591}
17592
ebb83eeb
KY
17593/* ***************** Mode7 ******************************/
17594static void alc663_mode7_unsol_event(struct hda_codec *codec,
17595 unsigned int res)
17596{
17597 switch (res >> 26) {
17598 case ALC880_HP_EVENT:
17599 alc663_two_hp_m7_speaker_automute(codec);
17600 break;
17601 case ALC880_MIC_EVENT:
17602 alc_mic_automute(codec);
17603 break;
17604 }
17605}
17606
17607#define alc663_mode7_setup alc663_mode1_setup
17608
17609static void alc663_mode7_inithook(struct hda_codec *codec)
17610{
17611 alc663_two_hp_m7_speaker_automute(codec);
17612 alc_mic_automute(codec);
17613}
17614
17615/* ***************** Mode8 ******************************/
17616static void alc663_mode8_unsol_event(struct hda_codec *codec,
17617 unsigned int res)
17618{
17619 switch (res >> 26) {
17620 case ALC880_HP_EVENT:
17621 alc663_two_hp_m8_speaker_automute(codec);
17622 break;
17623 case ALC880_MIC_EVENT:
17624 alc_mic_automute(codec);
17625 break;
17626 }
17627}
17628
17629#define alc663_mode8_setup alc663_m51va_setup
17630
17631static void alc663_mode8_inithook(struct hda_codec *codec)
17632{
17633 alc663_two_hp_m8_speaker_automute(codec);
17634 alc_mic_automute(codec);
17635}
17636
6dda9f4a
KY
17637static void alc663_g71v_hp_automute(struct hda_codec *codec)
17638{
17639 unsigned int present;
17640 unsigned char bits;
17641
864f92be 17642 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17643 bits = present ? HDA_AMP_MUTE : 0;
17644 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17645 HDA_AMP_MUTE, bits);
17646 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17647 HDA_AMP_MUTE, bits);
17648}
17649
17650static void alc663_g71v_front_automute(struct hda_codec *codec)
17651{
17652 unsigned int present;
17653 unsigned char bits;
17654
864f92be 17655 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17656 bits = present ? HDA_AMP_MUTE : 0;
17657 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17658 HDA_AMP_MUTE, bits);
17659}
17660
17661static void alc663_g71v_unsol_event(struct hda_codec *codec,
17662 unsigned int res)
17663{
17664 switch (res >> 26) {
17665 case ALC880_HP_EVENT:
17666 alc663_g71v_hp_automute(codec);
17667 break;
17668 case ALC880_FRONT_EVENT:
17669 alc663_g71v_front_automute(codec);
17670 break;
17671 case ALC880_MIC_EVENT:
4f5d1706 17672 alc_mic_automute(codec);
6dda9f4a
KY
17673 break;
17674 }
17675}
17676
4f5d1706
TI
17677#define alc663_g71v_setup alc663_m51va_setup
17678
6dda9f4a
KY
17679static void alc663_g71v_inithook(struct hda_codec *codec)
17680{
17681 alc663_g71v_front_automute(codec);
17682 alc663_g71v_hp_automute(codec);
4f5d1706 17683 alc_mic_automute(codec);
6dda9f4a
KY
17684}
17685
17686static void alc663_g50v_unsol_event(struct hda_codec *codec,
17687 unsigned int res)
17688{
17689 switch (res >> 26) {
17690 case ALC880_HP_EVENT:
17691 alc663_m51va_speaker_automute(codec);
17692 break;
17693 case ALC880_MIC_EVENT:
4f5d1706 17694 alc_mic_automute(codec);
6dda9f4a
KY
17695 break;
17696 }
17697}
17698
4f5d1706
TI
17699#define alc663_g50v_setup alc663_m51va_setup
17700
6dda9f4a
KY
17701static void alc663_g50v_inithook(struct hda_codec *codec)
17702{
17703 alc663_m51va_speaker_automute(codec);
4f5d1706 17704 alc_mic_automute(codec);
6dda9f4a
KY
17705}
17706
f1d4e28b
KY
17707static struct snd_kcontrol_new alc662_ecs_mixer[] = {
17708 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 17709 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
17710
17711 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
17712 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17713 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17714
17715 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17716 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17717 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17718 { } /* end */
17719};
17720
9541ba1d
CP
17721static struct snd_kcontrol_new alc272_nc10_mixer[] = {
17722 /* Master Playback automatically created from Speaker and Headphone */
17723 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17724 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17727
17728 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17729 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17730 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
17731
17732 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17733 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17734 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
17735 { } /* end */
17736};
17737
cb53c626
TI
17738#ifdef CONFIG_SND_HDA_POWER_SAVE
17739#define alc662_loopbacks alc880_loopbacks
17740#endif
17741
bc9f98a9 17742
def319f9 17743/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
17744#define alc662_pcm_analog_playback alc880_pcm_analog_playback
17745#define alc662_pcm_analog_capture alc880_pcm_analog_capture
17746#define alc662_pcm_digital_playback alc880_pcm_digital_playback
17747#define alc662_pcm_digital_capture alc880_pcm_digital_capture
17748
17749/*
17750 * configuration and preset
17751 */
17752static const char *alc662_models[ALC662_MODEL_LAST] = {
17753 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17754 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17755 [ALC662_3ST_6ch] = "3stack-6ch",
17756 [ALC662_5ST_DIG] = "6stack-dig",
17757 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 17758 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 17759 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 17760 [ALC662_ECS] = "ecs",
6dda9f4a
KY
17761 [ALC663_ASUS_M51VA] = "m51va",
17762 [ALC663_ASUS_G71V] = "g71v",
17763 [ALC663_ASUS_H13] = "h13",
17764 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
17765 [ALC663_ASUS_MODE1] = "asus-mode1",
17766 [ALC662_ASUS_MODE2] = "asus-mode2",
17767 [ALC663_ASUS_MODE3] = "asus-mode3",
17768 [ALC663_ASUS_MODE4] = "asus-mode4",
17769 [ALC663_ASUS_MODE5] = "asus-mode5",
17770 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
17771 [ALC663_ASUS_MODE7] = "asus-mode7",
17772 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
17773 [ALC272_DELL] = "dell",
17774 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 17775 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
17776 [ALC662_AUTO] = "auto",
17777};
17778
17779static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 17780 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
17781 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17782 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 17783 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 17784 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 17785 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 17786 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 17787 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 17788 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 17789 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
17790 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17791 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 17792 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17793 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17794 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17795 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17796 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17797 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 17798 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17799 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17800 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
17801 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17802 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17803 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17804 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 17805 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
17806 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17807 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17808 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 17809 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17810 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17811 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17812 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 17813 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 17814 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17815 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17816 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17817 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 17818 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 17819 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 17820 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 17821 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
17822 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17823 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
17824 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17825 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17826 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 17827 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
17828 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17829 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 17830 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
17831 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17832 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17833 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17834 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17835 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 17836 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 17837 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 17838 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
17839 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17840 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17841 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17842 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
17843 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17844 ALC662_3ST_6ch_DIG),
4dee8baa 17845 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 17846 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
17847 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17848 ALC662_3ST_6ch_DIG),
6227cdce 17849 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 17850 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 17851 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 17852 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 17853 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 17854 ALC662_3ST_6ch_DIG),
dea0a509
TI
17855 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17856 ALC663_ASUS_H13),
7aee6746 17857 SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
bc9f98a9
KY
17858 {}
17859};
17860
17861static struct alc_config_preset alc662_presets[] = {
17862 [ALC662_3ST_2ch_DIG] = {
f9e336f6 17863 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
17864 .init_verbs = { alc662_init_verbs },
17865 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17866 .dac_nids = alc662_dac_nids,
17867 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17868 .dig_in_nid = ALC662_DIGIN_NID,
17869 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17870 .channel_mode = alc662_3ST_2ch_modes,
17871 .input_mux = &alc662_capture_source,
17872 },
17873 [ALC662_3ST_6ch_DIG] = {
f9e336f6 17874 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17875 .init_verbs = { alc662_init_verbs },
17876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17877 .dac_nids = alc662_dac_nids,
17878 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17879 .dig_in_nid = ALC662_DIGIN_NID,
17880 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17881 .channel_mode = alc662_3ST_6ch_modes,
17882 .need_dac_fix = 1,
17883 .input_mux = &alc662_capture_source,
f12ab1e0 17884 },
bc9f98a9 17885 [ALC662_3ST_6ch] = {
f9e336f6 17886 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17887 .init_verbs = { alc662_init_verbs },
17888 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17889 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17891 .channel_mode = alc662_3ST_6ch_modes,
17892 .need_dac_fix = 1,
17893 .input_mux = &alc662_capture_source,
f12ab1e0 17894 },
bc9f98a9 17895 [ALC662_5ST_DIG] = {
f9e336f6 17896 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17897 .init_verbs = { alc662_init_verbs },
17898 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17899 .dac_nids = alc662_dac_nids,
17900 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17901 .dig_in_nid = ALC662_DIGIN_NID,
17902 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17903 .channel_mode = alc662_5stack_modes,
17904 .input_mux = &alc662_capture_source,
17905 },
17906 [ALC662_LENOVO_101E] = {
f9e336f6 17907 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
17908 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
17909 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17910 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17911 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17912 .channel_mode = alc662_3ST_2ch_modes,
17913 .input_mux = &alc662_lenovo_101e_capture_source,
17914 .unsol_event = alc662_lenovo_101e_unsol_event,
17915 .init_hook = alc662_lenovo_101e_all_automute,
17916 },
291702f0 17917 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 17918 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
17919 .init_verbs = { alc662_init_verbs,
17920 alc662_eeepc_sue_init_verbs },
17921 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17922 .dac_nids = alc662_dac_nids,
291702f0
KY
17923 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17924 .channel_mode = alc662_3ST_2ch_modes,
291702f0 17925 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17926 .setup = alc662_eeepc_setup,
291702f0
KY
17927 .init_hook = alc662_eeepc_inithook,
17928 },
8c427226 17929 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 17930 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
17931 alc662_chmode_mixer },
17932 .init_verbs = { alc662_init_verbs,
17933 alc662_eeepc_ep20_sue_init_verbs },
17934 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17935 .dac_nids = alc662_dac_nids,
8c427226
KY
17936 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17937 .channel_mode = alc662_3ST_6ch_modes,
17938 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 17939 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17940 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
17941 .init_hook = alc662_eeepc_ep20_inithook,
17942 },
f1d4e28b 17943 [ALC662_ECS] = {
f9e336f6 17944 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
17945 .init_verbs = { alc662_init_verbs,
17946 alc662_ecs_init_verbs },
17947 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17948 .dac_nids = alc662_dac_nids,
17949 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17950 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17951 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17952 .setup = alc662_eeepc_setup,
f1d4e28b
KY
17953 .init_hook = alc662_eeepc_inithook,
17954 },
6dda9f4a 17955 [ALC663_ASUS_M51VA] = {
f9e336f6 17956 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
17957 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17958 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17959 .dac_nids = alc662_dac_nids,
17960 .dig_out_nid = ALC662_DIGOUT_NID,
17961 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17962 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 17963 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17964 .setup = alc663_m51va_setup,
6dda9f4a
KY
17965 .init_hook = alc663_m51va_inithook,
17966 },
17967 [ALC663_ASUS_G71V] = {
f9e336f6 17968 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
17969 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17970 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17971 .dac_nids = alc662_dac_nids,
17972 .dig_out_nid = ALC662_DIGOUT_NID,
17973 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17974 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 17975 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 17976 .setup = alc663_g71v_setup,
6dda9f4a
KY
17977 .init_hook = alc663_g71v_inithook,
17978 },
17979 [ALC663_ASUS_H13] = {
f9e336f6 17980 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
17981 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17982 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17983 .dac_nids = alc662_dac_nids,
17984 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17985 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
17986 .unsol_event = alc663_m51va_unsol_event,
17987 .init_hook = alc663_m51va_inithook,
17988 },
17989 [ALC663_ASUS_G50V] = {
f9e336f6 17990 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
17991 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
17992 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17993 .dac_nids = alc662_dac_nids,
17994 .dig_out_nid = ALC662_DIGOUT_NID,
17995 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17996 .channel_mode = alc662_3ST_6ch_modes,
17997 .input_mux = &alc663_capture_source,
17998 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 17999 .setup = alc663_g50v_setup,
6dda9f4a
KY
18000 .init_hook = alc663_g50v_inithook,
18001 },
f1d4e28b 18002 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18003 .mixers = { alc663_m51va_mixer },
18004 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18005 .init_verbs = { alc662_init_verbs,
18006 alc663_21jd_amic_init_verbs },
18007 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18008 .hp_nid = 0x03,
18009 .dac_nids = alc662_dac_nids,
18010 .dig_out_nid = ALC662_DIGOUT_NID,
18011 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18012 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18013 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18014 .setup = alc663_mode1_setup,
f1d4e28b
KY
18015 .init_hook = alc663_mode1_inithook,
18016 },
18017 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18018 .mixers = { alc662_1bjd_mixer },
18019 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18020 .init_verbs = { alc662_init_verbs,
18021 alc662_1bjd_amic_init_verbs },
18022 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18023 .dac_nids = alc662_dac_nids,
18024 .dig_out_nid = ALC662_DIGOUT_NID,
18025 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18026 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18027 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18028 .setup = alc662_mode2_setup,
f1d4e28b
KY
18029 .init_hook = alc662_mode2_inithook,
18030 },
18031 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18032 .mixers = { alc663_two_hp_m1_mixer },
18033 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18034 .init_verbs = { alc662_init_verbs,
18035 alc663_two_hp_amic_m1_init_verbs },
18036 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18037 .hp_nid = 0x03,
18038 .dac_nids = alc662_dac_nids,
18039 .dig_out_nid = ALC662_DIGOUT_NID,
18040 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18041 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18042 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18043 .setup = alc663_mode3_setup,
f1d4e28b
KY
18044 .init_hook = alc663_mode3_inithook,
18045 },
18046 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18047 .mixers = { alc663_asus_21jd_clfe_mixer },
18048 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18049 .init_verbs = { alc662_init_verbs,
18050 alc663_21jd_amic_init_verbs},
18051 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18052 .hp_nid = 0x03,
18053 .dac_nids = alc662_dac_nids,
18054 .dig_out_nid = ALC662_DIGOUT_NID,
18055 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18056 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18057 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18058 .setup = alc663_mode4_setup,
f1d4e28b
KY
18059 .init_hook = alc663_mode4_inithook,
18060 },
18061 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18062 .mixers = { alc663_asus_15jd_clfe_mixer },
18063 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18064 .init_verbs = { alc662_init_verbs,
18065 alc663_15jd_amic_init_verbs },
18066 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18067 .hp_nid = 0x03,
18068 .dac_nids = alc662_dac_nids,
18069 .dig_out_nid = ALC662_DIGOUT_NID,
18070 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18071 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18072 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18073 .setup = alc663_mode5_setup,
f1d4e28b
KY
18074 .init_hook = alc663_mode5_inithook,
18075 },
18076 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18077 .mixers = { alc663_two_hp_m2_mixer },
18078 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18079 .init_verbs = { alc662_init_verbs,
18080 alc663_two_hp_amic_m2_init_verbs },
18081 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18082 .hp_nid = 0x03,
18083 .dac_nids = alc662_dac_nids,
18084 .dig_out_nid = ALC662_DIGOUT_NID,
18085 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18086 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18087 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18088 .setup = alc663_mode6_setup,
f1d4e28b
KY
18089 .init_hook = alc663_mode6_inithook,
18090 },
ebb83eeb
KY
18091 [ALC663_ASUS_MODE7] = {
18092 .mixers = { alc663_mode7_mixer },
18093 .cap_mixer = alc662_auto_capture_mixer,
18094 .init_verbs = { alc662_init_verbs,
18095 alc663_mode7_init_verbs },
18096 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18097 .hp_nid = 0x03,
18098 .dac_nids = alc662_dac_nids,
18099 .dig_out_nid = ALC662_DIGOUT_NID,
18100 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18101 .channel_mode = alc662_3ST_2ch_modes,
18102 .unsol_event = alc663_mode7_unsol_event,
18103 .setup = alc663_mode7_setup,
18104 .init_hook = alc663_mode7_inithook,
18105 },
18106 [ALC663_ASUS_MODE8] = {
18107 .mixers = { alc663_mode8_mixer },
18108 .cap_mixer = alc662_auto_capture_mixer,
18109 .init_verbs = { alc662_init_verbs,
18110 alc663_mode8_init_verbs },
18111 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18112 .hp_nid = 0x03,
18113 .dac_nids = alc662_dac_nids,
18114 .dig_out_nid = ALC662_DIGOUT_NID,
18115 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18116 .channel_mode = alc662_3ST_2ch_modes,
18117 .unsol_event = alc663_mode8_unsol_event,
18118 .setup = alc663_mode8_setup,
18119 .init_hook = alc663_mode8_inithook,
18120 },
622e84cd
KY
18121 [ALC272_DELL] = {
18122 .mixers = { alc663_m51va_mixer },
18123 .cap_mixer = alc272_auto_capture_mixer,
18124 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18125 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18126 .dac_nids = alc662_dac_nids,
18127 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18128 .adc_nids = alc272_adc_nids,
18129 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18130 .capsrc_nids = alc272_capsrc_nids,
18131 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18132 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18133 .setup = alc663_m51va_setup,
622e84cd
KY
18134 .init_hook = alc663_m51va_inithook,
18135 },
18136 [ALC272_DELL_ZM1] = {
18137 .mixers = { alc663_m51va_mixer },
18138 .cap_mixer = alc662_auto_capture_mixer,
18139 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18140 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18141 .dac_nids = alc662_dac_nids,
18142 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18143 .adc_nids = alc662_adc_nids,
b59bdf3b 18144 .num_adc_nids = 1,
622e84cd
KY
18145 .capsrc_nids = alc662_capsrc_nids,
18146 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18147 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18148 .setup = alc663_m51va_setup,
622e84cd
KY
18149 .init_hook = alc663_m51va_inithook,
18150 },
9541ba1d
CP
18151 [ALC272_SAMSUNG_NC10] = {
18152 .mixers = { alc272_nc10_mixer },
18153 .init_verbs = { alc662_init_verbs,
18154 alc663_21jd_amic_init_verbs },
18155 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18156 .dac_nids = alc272_dac_nids,
18157 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18158 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18159 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18160 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18161 .setup = alc663_mode4_setup,
9541ba1d
CP
18162 .init_hook = alc663_mode4_inithook,
18163 },
bc9f98a9
KY
18164};
18165
18166
18167/*
18168 * BIOS auto configuration
18169 */
18170
7085ec12
TI
18171/* convert from MIX nid to DAC */
18172static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18173{
18174 if (nid == 0x0f)
18175 return 0x02;
18176 else if (nid >= 0x0c && nid <= 0x0e)
18177 return nid - 0x0c + 0x02;
18178 else
18179 return 0;
18180}
18181
18182/* get MIX nid connected to the given pin targeted to DAC */
18183static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18184 hda_nid_t dac)
18185{
18186 hda_nid_t mix[4];
18187 int i, num;
18188
18189 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18190 for (i = 0; i < num; i++) {
18191 if (alc662_mix_to_dac(mix[i]) == dac)
18192 return mix[i];
18193 }
18194 return 0;
18195}
18196
18197/* look for an empty DAC slot */
18198static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18199{
18200 struct alc_spec *spec = codec->spec;
18201 hda_nid_t srcs[5];
18202 int i, j, num;
18203
18204 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18205 if (num < 0)
18206 return 0;
18207 for (i = 0; i < num; i++) {
18208 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18209 if (!nid)
18210 continue;
18211 for (j = 0; j < spec->multiout.num_dacs; j++)
18212 if (spec->multiout.dac_nids[j] == nid)
18213 break;
18214 if (j >= spec->multiout.num_dacs)
18215 return nid;
18216 }
18217 return 0;
18218}
18219
18220/* fill in the dac_nids table from the parsed pin configuration */
18221static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18222 const struct auto_pin_cfg *cfg)
18223{
18224 struct alc_spec *spec = codec->spec;
18225 int i;
18226 hda_nid_t dac;
18227
18228 spec->multiout.dac_nids = spec->private_dac_nids;
18229 for (i = 0; i < cfg->line_outs; i++) {
18230 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18231 if (!dac)
18232 continue;
18233 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18234 }
18235 return 0;
18236}
18237
0afe5f89 18238static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18239 hda_nid_t nid, unsigned int chs)
18240{
0afe5f89 18241 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18242 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18243}
18244
0afe5f89 18245static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18246 hda_nid_t nid, unsigned int chs)
18247{
0afe5f89 18248 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18249 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18250}
18251
18252#define alc662_add_stereo_vol(spec, pfx, nid) \
18253 alc662_add_vol_ctl(spec, pfx, nid, 3)
18254#define alc662_add_stereo_sw(spec, pfx, nid) \
18255 alc662_add_sw_ctl(spec, pfx, nid, 3)
18256
bc9f98a9 18257/* add playback controls from the parsed DAC table */
7085ec12 18258static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18259 const struct auto_pin_cfg *cfg)
18260{
7085ec12 18261 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18262 static const char *chname[4] = {
18263 "Front", "Surround", NULL /*CLFE*/, "Side"
18264 };
7085ec12 18265 hda_nid_t nid, mix;
bc9f98a9
KY
18266 int i, err;
18267
18268 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18269 nid = spec->multiout.dac_nids[i];
18270 if (!nid)
18271 continue;
18272 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18273 if (!mix)
bc9f98a9 18274 continue;
bc9f98a9
KY
18275 if (i == 2) {
18276 /* Center/LFE */
7085ec12 18277 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18278 if (err < 0)
18279 return err;
7085ec12 18280 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18281 if (err < 0)
18282 return err;
7085ec12 18283 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18284 if (err < 0)
18285 return err;
7085ec12 18286 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18287 if (err < 0)
18288 return err;
18289 } else {
0d884cb9
TI
18290 const char *pfx;
18291 if (cfg->line_outs == 1 &&
18292 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18293 if (cfg->hp_outs)
0d884cb9
TI
18294 pfx = "Speaker";
18295 else
18296 pfx = "PCM";
18297 } else
18298 pfx = chname[i];
7085ec12 18299 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18300 if (err < 0)
18301 return err;
0d884cb9
TI
18302 if (cfg->line_outs == 1 &&
18303 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18304 pfx = "Speaker";
7085ec12 18305 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18306 if (err < 0)
18307 return err;
18308 }
18309 }
18310 return 0;
18311}
18312
18313/* add playback controls for speaker and HP outputs */
7085ec12
TI
18314/* return DAC nid if any new DAC is assigned */
18315static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18316 const char *pfx)
18317{
7085ec12
TI
18318 struct alc_spec *spec = codec->spec;
18319 hda_nid_t nid, mix;
bc9f98a9 18320 int err;
bc9f98a9
KY
18321
18322 if (!pin)
18323 return 0;
7085ec12
TI
18324 nid = alc662_look_for_dac(codec, pin);
18325 if (!nid) {
7085ec12
TI
18326 /* the corresponding DAC is already occupied */
18327 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18328 return 0; /* no way */
18329 /* create a switch only */
0afe5f89 18330 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18331 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18332 }
18333
7085ec12
TI
18334 mix = alc662_dac_to_mix(codec, pin, nid);
18335 if (!mix)
18336 return 0;
18337 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18338 if (err < 0)
18339 return err;
18340 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18341 if (err < 0)
18342 return err;
18343 return nid;
bc9f98a9
KY
18344}
18345
18346/* create playback/capture controls for input pins */
05f5f477 18347#define alc662_auto_create_input_ctls \
4b7348a1 18348 alc882_auto_create_input_ctls
bc9f98a9
KY
18349
18350static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18351 hda_nid_t nid, int pin_type,
7085ec12 18352 hda_nid_t dac)
bc9f98a9 18353{
7085ec12
TI
18354 int i, num;
18355 hda_nid_t srcs[4];
18356
f6c7e546 18357 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18358 /* need the manual connection? */
7085ec12
TI
18359 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18360 if (num <= 1)
18361 return;
18362 for (i = 0; i < num; i++) {
18363 if (alc662_mix_to_dac(srcs[i]) != dac)
18364 continue;
18365 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18366 return;
bc9f98a9
KY
18367 }
18368}
18369
18370static void alc662_auto_init_multi_out(struct hda_codec *codec)
18371{
18372 struct alc_spec *spec = codec->spec;
7085ec12 18373 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18374 int i;
18375
18376 for (i = 0; i <= HDA_SIDE; i++) {
18377 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18378 if (nid)
baba8ee9 18379 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18380 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18381 }
18382}
18383
18384static void alc662_auto_init_hp_out(struct hda_codec *codec)
18385{
18386 struct alc_spec *spec = codec->spec;
18387 hda_nid_t pin;
18388
18389 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18390 if (pin)
18391 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18392 spec->multiout.hp_nid);
f6c7e546
TI
18393 pin = spec->autocfg.speaker_pins[0];
18394 if (pin)
7085ec12
TI
18395 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18396 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18397}
18398
bc9f98a9
KY
18399#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18400
18401static void alc662_auto_init_analog_input(struct hda_codec *codec)
18402{
18403 struct alc_spec *spec = codec->spec;
18404 int i;
18405
18406 for (i = 0; i < AUTO_PIN_LAST; i++) {
18407 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18408 if (alc_is_input_pin(codec, nid)) {
23f0c048 18409 alc_set_input_pin(codec, nid, i);
52ca15b7 18410 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18411 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18412 snd_hda_codec_write(codec, nid, 0,
18413 AC_VERB_SET_AMP_GAIN_MUTE,
18414 AMP_OUT_MUTE);
18415 }
18416 }
18417}
18418
f511b01c
TI
18419#define alc662_auto_init_input_src alc882_auto_init_input_src
18420
bc9f98a9
KY
18421static int alc662_parse_auto_config(struct hda_codec *codec)
18422{
18423 struct alc_spec *spec = codec->spec;
18424 int err;
18425 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18426
18427 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18428 alc662_ignore);
18429 if (err < 0)
18430 return err;
18431 if (!spec->autocfg.line_outs)
18432 return 0; /* can't find valid BIOS pin config */
18433
7085ec12 18434 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18435 if (err < 0)
18436 return err;
7085ec12 18437 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18438 if (err < 0)
18439 return err;
7085ec12 18440 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18441 spec->autocfg.speaker_pins[0],
18442 "Speaker");
18443 if (err < 0)
18444 return err;
7085ec12
TI
18445 if (err)
18446 spec->multiout.extra_out_nid[0] = err;
18447 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18448 "Headphone");
18449 if (err < 0)
18450 return err;
7085ec12
TI
18451 if (err)
18452 spec->multiout.hp_nid = err;
05f5f477 18453 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18454 if (err < 0)
bc9f98a9
KY
18455 return err;
18456
18457 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18458
0852d7a6 18459 if (spec->autocfg.dig_outs)
bc9f98a9
KY
18460 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18461
603c4019 18462 if (spec->kctls.list)
d88897ea 18463 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18464
18465 spec->num_mux_defs = 1;
61b9b9b1 18466 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18467
cec27c89
KY
18468 add_verb(spec, alc662_init_verbs);
18469 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18470 codec->vendor_id == 0x10ec0665)
18471 add_verb(spec, alc663_init_verbs);
18472
18473 if (codec->vendor_id == 0x10ec0272)
18474 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18475
18476 err = alc_auto_add_mic_boost(codec);
18477 if (err < 0)
18478 return err;
18479
6227cdce
KY
18480 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18481 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18482 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18483 else
18484 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18485
8c87286f 18486 return 1;
bc9f98a9
KY
18487}
18488
18489/* additional initialization for auto-configuration model */
18490static void alc662_auto_init(struct hda_codec *codec)
18491{
f6c7e546 18492 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18493 alc662_auto_init_multi_out(codec);
18494 alc662_auto_init_hp_out(codec);
18495 alc662_auto_init_analog_input(codec);
f511b01c 18496 alc662_auto_init_input_src(codec);
f6c7e546 18497 if (spec->unsol_event)
7fb0d78f 18498 alc_inithook(codec);
bc9f98a9
KY
18499}
18500
18501static int patch_alc662(struct hda_codec *codec)
18502{
18503 struct alc_spec *spec;
18504 int err, board_config;
18505
18506 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18507 if (!spec)
18508 return -ENOMEM;
18509
18510 codec->spec = spec;
18511
da00c244
KY
18512 alc_auto_parse_customize_define(codec);
18513
2c3bf9ab
TI
18514 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18515
c027ddcd
KY
18516 if (alc_read_coef_idx(codec, 0) == 0x8020)
18517 alc_codec_rename(codec, "ALC661");
18518 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18519 codec->bus->pci->subsystem_vendor == 0x1025 &&
18520 spec->cdefine.platform_type == 1)
18521 alc_codec_rename(codec, "ALC272X");
274693f3 18522
bc9f98a9
KY
18523 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18524 alc662_models,
18525 alc662_cfg_tbl);
18526 if (board_config < 0) {
9a11f1aa
TI
18527 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18528 codec->chip_name);
bc9f98a9
KY
18529 board_config = ALC662_AUTO;
18530 }
18531
18532 if (board_config == ALC662_AUTO) {
18533 /* automatic parse from the BIOS config */
18534 err = alc662_parse_auto_config(codec);
18535 if (err < 0) {
18536 alc_free(codec);
18537 return err;
8c87286f 18538 } else if (!err) {
bc9f98a9
KY
18539 printk(KERN_INFO
18540 "hda_codec: Cannot set up configuration "
18541 "from BIOS. Using base mode...\n");
18542 board_config = ALC662_3ST_2ch_DIG;
18543 }
18544 }
18545
680cd536
KK
18546 err = snd_hda_attach_beep_device(codec, 0x1);
18547 if (err < 0) {
18548 alc_free(codec);
18549 return err;
18550 }
18551
bc9f98a9 18552 if (board_config != ALC662_AUTO)
e9c364c0 18553 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18554
bc9f98a9
KY
18555 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18556 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18557
bc9f98a9
KY
18558 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18559 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18560
dd704698
TI
18561 if (!spec->adc_nids) {
18562 spec->adc_nids = alc662_adc_nids;
18563 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18564 }
18565 if (!spec->capsrc_nids)
18566 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18567
f9e336f6 18568 if (!spec->cap_mixer)
b59bdf3b 18569 set_capture_mixer(codec);
cec27c89 18570
da00c244
KY
18571 if (spec->cdefine.enable_pcbeep) {
18572 switch (codec->vendor_id) {
18573 case 0x10ec0662:
18574 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18575 break;
18576 case 0x10ec0272:
18577 case 0x10ec0663:
18578 case 0x10ec0665:
18579 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18580 break;
18581 case 0x10ec0273:
18582 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18583 break;
18584 }
cec27c89 18585 }
2134ea4f
TI
18586 spec->vmaster_nid = 0x02;
18587
bc9f98a9
KY
18588 codec->patch_ops = alc_patch_ops;
18589 if (board_config == ALC662_AUTO)
18590 spec->init_hook = alc662_auto_init;
cb53c626
TI
18591#ifdef CONFIG_SND_HDA_POWER_SAVE
18592 if (!spec->loopback.amplist)
18593 spec->loopback.amplist = alc662_loopbacks;
18594#endif
bc9f98a9
KY
18595
18596 return 0;
18597}
18598
274693f3
KY
18599static int patch_alc888(struct hda_codec *codec)
18600{
18601 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18602 kfree(codec->chip_name);
18603 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18604 if (!codec->chip_name) {
18605 alc_free(codec);
274693f3 18606 return -ENOMEM;
ac2c92e0
TI
18607 }
18608 return patch_alc662(codec);
274693f3 18609 }
ac2c92e0 18610 return patch_alc882(codec);
274693f3
KY
18611}
18612
1da177e4
LT
18613/*
18614 * patch entries
18615 */
1289e9e8 18616static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 18617 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 18618 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 18619 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 18620 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 18621 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 18622 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 18623 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 18624 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 18625 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 18626 .patch = patch_alc861 },
f32610ed
JS
18627 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
18628 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
18629 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 18630 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 18631 .patch = patch_alc882 },
bc9f98a9
KY
18632 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18633 .patch = patch_alc662 },
6dda9f4a 18634 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 18635 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 18636 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
f32610ed 18637 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 18638 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 18639 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 18640 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 18641 .patch = patch_alc882 },
cb308f97 18642 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 18643 .patch = patch_alc882 },
df694daa 18644 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 18645 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 18646 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 18647 .patch = patch_alc882 },
274693f3 18648 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 18649 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 18650 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
18651 {} /* terminator */
18652};
1289e9e8
TI
18653
18654MODULE_ALIAS("snd-hda-codec-id:10ec*");
18655
18656MODULE_LICENSE("GPL");
18657MODULE_DESCRIPTION("Realtek HD-audio codec");
18658
18659static struct hda_codec_preset_list realtek_list = {
18660 .preset = snd_hda_preset_realtek,
18661 .owner = THIS_MODULE,
18662};
18663
18664static int __init patch_realtek_init(void)
18665{
18666 return snd_hda_add_codec_preset(&realtek_list);
18667}
18668
18669static void __exit patch_realtek_exit(void)
18670{
18671 snd_hda_delete_codec_preset(&realtek_list);
18672}
18673
18674module_init(patch_realtek_init)
18675module_exit(patch_realtek_exit)
This page took 2.195748 seconds and 5 git commands to generate.