]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/hda/patch_realtek.c
Merge branch 'fix/hda' into topic/hda
[net-next-2.6.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
680cd536 33#include "hda_beep.h"
1da177e4 34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
df99cd33 63 ALC880_MEDION_RIM,
e9edcee0
TI
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
df694daa 67 ALC880_AUTO,
16ded525
TI
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
3f878308 75 ALC260_HP_DC7600,
df694daa
KY
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
0bfc90e9 78 ALC260_ACER,
bc9f98a9
KY
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
cc959489 81 ALC260_FAVORIT100,
7cf51e48
JW
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
df694daa 85 ALC260_AUTO,
16ded525 86 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
87};
88
df694daa
KY
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
ccc656ce
KY
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
834be88d 94 ALC262_FUJITSU,
9c7f852e 95 ALC262_HP_BPC,
cd7509a4
KY
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
66d2a9d6 98 ALC262_HP_TC_T5735,
8c427226 99 ALC262_HP_RP5700,
304dcaac 100 ALC262_BENQ_ED8,
272a527c 101 ALC262_SONY_ASSAMD,
83c34218 102 ALC262_BENQ_T31,
f651b50b 103 ALC262_ULTRA,
0e31daf7 104 ALC262_LENOVO_3000,
e8f9ae2a 105 ALC262_NEC,
4e555fe5 106 ALC262_TOSHIBA_S06,
9f99a638 107 ALC262_TOSHIBA_RX1,
ba340e82 108 ALC262_TYAN,
df694daa
KY
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
a361d84b
KY
113/* ALC268 models */
114enum {
eb5a6621 115 ALC267_QUANTA_IL1,
a361d84b 116 ALC268_3ST,
d1a991a6 117 ALC268_TOSHIBA,
d273809e 118 ALC268_ACER,
c238b4f4 119 ALC268_ACER_DMIC,
8ef355da 120 ALC268_ACER_ASPIRE_ONE,
3866f0b0 121 ALC268_DELL,
f12462c5 122 ALC268_ZEPTO,
86c53bd2
JW
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
a361d84b
KY
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
f6a92248
KY
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
60db6b53 133 ALC269_QUANTA_FL1,
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[] = {
d1284182
TV
1693/* Route to built-in subwoofer as well as speakers */
1694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1696 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1697 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1698/* Bias voltage on for external mic port */
1699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1700/* Front Mic: set to PIN_IN (empty by default) */
1701 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1702/* Unselect Front Mic by default in input mixer 3 */
1703 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1704/* Enable unsolicited event for HP jack */
1705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1706/* Enable speaker output */
1707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1709 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1710/* Enable headphone output */
1711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1714 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1715 { }
1716};
1717
3b315d70 1718/*
018df418 1719 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1720 */
1721
018df418 1722static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1723/* Front Mic: set to PIN_IN (empty by default) */
1724 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1725/* Unselect Front Mic by default in input mixer 3 */
1726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1727/* Enable unsolicited event for HP jack */
1728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1729/* Connect Internal Front to Front */
1730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1733/* Connect Internal Rear to Rear */
1734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1736 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1737/* Connect Internal CLFE to CLFE */
1738 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1740 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1741/* Connect HP out to Front */
018df418 1742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1743 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1745/* Enable all DACs */
1746/* DAC DISABLE/MUTE 1? */
1747/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1748 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1749 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1750/* DAC DISABLE/MUTE 2? */
1751/* some bit here disables the other DACs. Init=0x4900 */
1752 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1753 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1754/* DMIC fix
1755 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1756 * which makes the stereo useless. However, either the mic or the ALC889
1757 * makes the signal become a difference/sum signal instead of standard
1758 * stereo, which is annoying. So instead we flip this bit which makes the
1759 * codec replicate the sum signal to both channels, turning it into a
1760 * normal mono mic.
1761 */
1762/* DMIC_CONTROL? Init value = 0x0001 */
1763 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1764 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1765 { }
1766};
1767
ef8ef5fb 1768static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1769 /* Front mic only available on one ADC */
1770 {
1771 .num_items = 4,
1772 .items = {
1773 { "Mic", 0x0 },
1774 { "Line", 0x2 },
1775 { "CD", 0x4 },
1776 { "Front Mic", 0xb },
1777 },
1778 },
1779 {
1780 .num_items = 3,
1781 .items = {
1782 { "Mic", 0x0 },
1783 { "Line", 0x2 },
1784 { "CD", 0x4 },
1785 },
1786 }
1787};
1788
d2fd4b09
TV
1789static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1790 /* Interal mic only available on one ADC */
1791 {
684a8842 1792 .num_items = 5,
d2fd4b09
TV
1793 .items = {
1794 { "Ext Mic", 0x0 },
684a8842 1795 { "Line In", 0x2 },
d2fd4b09 1796 { "CD", 0x4 },
684a8842 1797 { "Input Mix", 0xa },
d2fd4b09
TV
1798 { "Int Mic", 0xb },
1799 },
1800 },
1801 {
684a8842 1802 .num_items = 4,
d2fd4b09
TV
1803 .items = {
1804 { "Ext Mic", 0x0 },
684a8842 1805 { "Line In", 0x2 },
d2fd4b09 1806 { "CD", 0x4 },
684a8842 1807 { "Input Mix", 0xa },
d2fd4b09
TV
1808 },
1809 }
1810};
1811
018df418
HM
1812static struct hda_input_mux alc889_capture_sources[3] = {
1813 /* Digital mic only available on first "ADC" */
1814 {
1815 .num_items = 5,
1816 .items = {
1817 { "Mic", 0x0 },
1818 { "Line", 0x2 },
1819 { "CD", 0x4 },
1820 { "Front Mic", 0xb },
1821 { "Input Mix", 0xa },
1822 },
1823 },
1824 {
1825 .num_items = 4,
1826 .items = {
1827 { "Mic", 0x0 },
1828 { "Line", 0x2 },
1829 { "CD", 0x4 },
1830 { "Input Mix", 0xa },
1831 },
1832 },
1833 {
1834 .num_items = 4,
1835 .items = {
1836 { "Mic", 0x0 },
1837 { "Line", 0x2 },
1838 { "CD", 0x4 },
1839 { "Input Mix", 0xa },
1840 },
1841 }
1842};
1843
ef8ef5fb 1844static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1845 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1846 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1847 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1848 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1849 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1850 HDA_OUTPUT),
1851 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1852 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1853 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1854 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1855 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1863 { } /* end */
1864};
1865
556eea9a
HM
1866static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1869 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1870 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1871 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1872 HDA_OUTPUT),
1873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1874 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1875 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1876 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1877 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1879 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1881 { } /* end */
1882};
1883
1884
4f5d1706 1885static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 1886{
a9fd4f3f 1887 struct alc_spec *spec = codec->spec;
5b2d1eca 1888
a9fd4f3f
TI
1889 spec->autocfg.hp_pins[0] = 0x15;
1890 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
1891 spec->autocfg.speaker_pins[1] = 0x16;
1892 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
1893}
1894
4f5d1706 1895static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
1896{
1897 struct alc_spec *spec = codec->spec;
1898
1899 spec->autocfg.hp_pins[0] = 0x15;
1900 spec->autocfg.speaker_pins[0] = 0x14;
1901 spec->autocfg.speaker_pins[1] = 0x16;
1902 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
1903}
1904
4f5d1706 1905static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
1906{
1907 struct alc_spec *spec = codec->spec;
1908
1909 spec->autocfg.hp_pins[0] = 0x15;
1910 spec->autocfg.speaker_pins[0] = 0x14;
1911 spec->autocfg.speaker_pins[1] = 0x16;
1912 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
1913}
1914
1da177e4 1915/*
e9edcee0
TI
1916 * ALC880 3-stack model
1917 *
1918 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1919 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1920 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1921 */
1922
e9edcee0
TI
1923static hda_nid_t alc880_dac_nids[4] = {
1924 /* front, rear, clfe, rear_surr */
1925 0x02, 0x05, 0x04, 0x03
1926};
1927
1928static hda_nid_t alc880_adc_nids[3] = {
1929 /* ADC0-2 */
1930 0x07, 0x08, 0x09,
1931};
1932
1933/* The datasheet says the node 0x07 is connected from inputs,
1934 * but it shows zero connection in the real implementation on some devices.
df694daa 1935 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1936 */
e9edcee0
TI
1937static hda_nid_t alc880_adc_nids_alt[2] = {
1938 /* ADC1-2 */
1939 0x08, 0x09,
1940};
1941
1942#define ALC880_DIGOUT_NID 0x06
1943#define ALC880_DIGIN_NID 0x0a
1944
1945static struct hda_input_mux alc880_capture_source = {
1946 .num_items = 4,
1947 .items = {
1948 { "Mic", 0x0 },
1949 { "Front Mic", 0x3 },
1950 { "Line", 0x2 },
1951 { "CD", 0x4 },
1952 },
1953};
1954
1955/* channel source setting (2/6 channel selection for 3-stack) */
1956/* 2ch mode */
1957static struct hda_verb alc880_threestack_ch2_init[] = {
1958 /* set line-in to input, mute it */
1959 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1960 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1961 /* set mic-in to input vref 80%, mute it */
1962 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1963 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1964 { } /* end */
1965};
1966
1967/* 6ch mode */
1968static struct hda_verb alc880_threestack_ch6_init[] = {
1969 /* set line-in to output, unmute it */
1970 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1971 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1972 /* set mic-in to output, unmute it */
1973 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1974 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1975 { } /* end */
1976};
1977
d2a6d7dc 1978static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1979 { 2, alc880_threestack_ch2_init },
1980 { 6, alc880_threestack_ch6_init },
1981};
1982
c8b6bf9b 1983static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1984 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1985 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1986 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1987 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1988 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1989 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1990 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1991 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2001 {
2002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2003 .name = "Channel Mode",
df694daa
KY
2004 .info = alc_ch_mode_info,
2005 .get = alc_ch_mode_get,
2006 .put = alc_ch_mode_put,
e9edcee0
TI
2007 },
2008 { } /* end */
2009};
2010
2011/* capture mixer elements */
f9e336f6
TI
2012static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2013 struct snd_ctl_elem_info *uinfo)
2014{
2015 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2016 struct alc_spec *spec = codec->spec;
2017 int err;
1da177e4 2018
5a9e02e9 2019 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2020 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2021 HDA_INPUT);
2022 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2023 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2024 return err;
2025}
2026
2027static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2028 unsigned int size, unsigned int __user *tlv)
2029{
2030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2031 struct alc_spec *spec = codec->spec;
2032 int err;
1da177e4 2033
5a9e02e9 2034 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2035 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2036 HDA_INPUT);
2037 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2038 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2039 return err;
2040}
2041
2042typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2043 struct snd_ctl_elem_value *ucontrol);
2044
2045static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2046 struct snd_ctl_elem_value *ucontrol,
2047 getput_call_t func)
2048{
2049 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2050 struct alc_spec *spec = codec->spec;
2051 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2052 int err;
2053
5a9e02e9 2054 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2055 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2056 3, 0, HDA_INPUT);
2057 err = func(kcontrol, ucontrol);
5a9e02e9 2058 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2059 return err;
2060}
2061
2062static int alc_cap_vol_get(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_get);
2067}
2068
2069static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2070 struct snd_ctl_elem_value *ucontrol)
2071{
2072 return alc_cap_getput_caller(kcontrol, ucontrol,
2073 snd_hda_mixer_amp_volume_put);
2074}
2075
2076/* capture mixer elements */
2077#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2078
2079static int alc_cap_sw_get(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_get);
2084}
2085
2086static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2087 struct snd_ctl_elem_value *ucontrol)
2088{
2089 return alc_cap_getput_caller(kcontrol, ucontrol,
2090 snd_hda_mixer_amp_switch_put);
2091}
2092
a23b688f 2093#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2094 { \
2095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2096 .name = "Capture Switch", \
2097 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2098 .count = num, \
2099 .info = alc_cap_sw_info, \
2100 .get = alc_cap_sw_get, \
2101 .put = alc_cap_sw_put, \
2102 }, \
2103 { \
2104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2105 .name = "Capture Volume", \
2106 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2107 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2108 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2109 .count = num, \
2110 .info = alc_cap_vol_info, \
2111 .get = alc_cap_vol_get, \
2112 .put = alc_cap_vol_put, \
2113 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2114 }
2115
2116#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2117 { \
2118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2119 /* .name = "Capture Source", */ \
2120 .name = "Input Source", \
2121 .count = num, \
2122 .info = alc_mux_enum_info, \
2123 .get = alc_mux_enum_get, \
2124 .put = alc_mux_enum_put, \
a23b688f
TI
2125 }
2126
2127#define DEFINE_CAPMIX(num) \
2128static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2129 _DEFINE_CAPMIX(num), \
2130 _DEFINE_CAPSRC(num), \
2131 { } /* end */ \
2132}
2133
2134#define DEFINE_CAPMIX_NOSRC(num) \
2135static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2136 _DEFINE_CAPMIX(num), \
2137 { } /* end */ \
f9e336f6
TI
2138}
2139
2140/* up to three ADCs */
2141DEFINE_CAPMIX(1);
2142DEFINE_CAPMIX(2);
2143DEFINE_CAPMIX(3);
a23b688f
TI
2144DEFINE_CAPMIX_NOSRC(1);
2145DEFINE_CAPMIX_NOSRC(2);
2146DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2147
2148/*
2149 * ALC880 5-stack model
2150 *
9c7f852e
TI
2151 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2152 * Side = 0x02 (0xd)
e9edcee0
TI
2153 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2154 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2155 */
2156
2157/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2158static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2159 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2160 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2161 { } /* end */
2162};
2163
e9edcee0
TI
2164/* channel source setting (6/8 channel selection for 5-stack) */
2165/* 6ch mode */
2166static struct hda_verb alc880_fivestack_ch6_init[] = {
2167 /* set line-in to input, mute it */
2168 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2169 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2170 { } /* end */
2171};
2172
e9edcee0
TI
2173/* 8ch mode */
2174static struct hda_verb alc880_fivestack_ch8_init[] = {
2175 /* set line-in to output, unmute it */
2176 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2177 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2178 { } /* end */
2179};
2180
d2a6d7dc 2181static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2182 { 6, alc880_fivestack_ch6_init },
2183 { 8, alc880_fivestack_ch8_init },
2184};
2185
2186
2187/*
2188 * ALC880 6-stack model
2189 *
9c7f852e
TI
2190 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2191 * Side = 0x05 (0x0f)
e9edcee0
TI
2192 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2193 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2194 */
2195
2196static hda_nid_t alc880_6st_dac_nids[4] = {
2197 /* front, rear, clfe, rear_surr */
2198 0x02, 0x03, 0x04, 0x05
f12ab1e0 2199};
e9edcee0
TI
2200
2201static struct hda_input_mux alc880_6stack_capture_source = {
2202 .num_items = 4,
2203 .items = {
2204 { "Mic", 0x0 },
2205 { "Front Mic", 0x1 },
2206 { "Line", 0x2 },
2207 { "CD", 0x4 },
2208 },
2209};
2210
2211/* fixed 8-channels */
d2a6d7dc 2212static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2213 { 8, NULL },
2214};
2215
c8b6bf9b 2216static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2217 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2218 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2219 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2220 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2221 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2222 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2223 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2224 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2225 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2226 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2227 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2228 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2230 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2231 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2232 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2234 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2235 {
2236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2237 .name = "Channel Mode",
df694daa
KY
2238 .info = alc_ch_mode_info,
2239 .get = alc_ch_mode_get,
2240 .put = alc_ch_mode_put,
16ded525
TI
2241 },
2242 { } /* end */
2243};
2244
e9edcee0
TI
2245
2246/*
2247 * ALC880 W810 model
2248 *
2249 * W810 has rear IO for:
2250 * Front (DAC 02)
2251 * Surround (DAC 03)
2252 * Center/LFE (DAC 04)
2253 * Digital out (06)
2254 *
2255 * The system also has a pair of internal speakers, and a headphone jack.
2256 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2257 *
e9edcee0
TI
2258 * There is a variable resistor to control the speaker or headphone
2259 * volume. This is a hardware-only device without a software API.
2260 *
2261 * Plugging headphones in will disable the internal speakers. This is
2262 * implemented in hardware, not via the driver using jack sense. In
2263 * a similar fashion, plugging into the rear socket marked "front" will
2264 * disable both the speakers and headphones.
2265 *
2266 * For input, there's a microphone jack, and an "audio in" jack.
2267 * These may not do anything useful with this driver yet, because I
2268 * haven't setup any initialization verbs for these yet...
2269 */
2270
2271static hda_nid_t alc880_w810_dac_nids[3] = {
2272 /* front, rear/surround, clfe */
2273 0x02, 0x03, 0x04
16ded525
TI
2274};
2275
e9edcee0 2276/* fixed 6 channels */
d2a6d7dc 2277static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2278 { 6, NULL }
2279};
2280
2281/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2282static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2283 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2284 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2285 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2286 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2287 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2288 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2289 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2290 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2292 { } /* end */
2293};
2294
2295
2296/*
2297 * Z710V model
2298 *
2299 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2300 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2301 * Line = 0x1a
e9edcee0
TI
2302 */
2303
2304static hda_nid_t alc880_z71v_dac_nids[1] = {
2305 0x02
2306};
2307#define ALC880_Z71V_HP_DAC 0x03
2308
2309/* fixed 2 channels */
d2a6d7dc 2310static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2311 { 2, NULL }
2312};
2313
c8b6bf9b 2314static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2315 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2316 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2318 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2319 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2320 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2322 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2323 { } /* end */
2324};
2325
e9edcee0 2326
e9edcee0
TI
2327/*
2328 * ALC880 F1734 model
2329 *
2330 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2331 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2332 */
2333
2334static hda_nid_t alc880_f1734_dac_nids[1] = {
2335 0x03
2336};
2337#define ALC880_F1734_HP_DAC 0x02
2338
c8b6bf9b 2339static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2341 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2342 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2343 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2344 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2345 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2348 { } /* end */
2349};
2350
937b4160
TI
2351static struct hda_input_mux alc880_f1734_capture_source = {
2352 .num_items = 2,
2353 .items = {
2354 { "Mic", 0x1 },
2355 { "CD", 0x4 },
2356 },
2357};
2358
e9edcee0 2359
e9edcee0
TI
2360/*
2361 * ALC880 ASUS model
2362 *
2363 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2364 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2365 * Mic = 0x18, Line = 0x1a
2366 */
2367
2368#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2369#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2370
c8b6bf9b 2371static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2372 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2373 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2374 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2375 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2376 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2377 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2378 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2379 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2380 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2381 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2382 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2383 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2384 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2385 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2386 {
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = "Channel Mode",
df694daa
KY
2389 .info = alc_ch_mode_info,
2390 .get = alc_ch_mode_get,
2391 .put = alc_ch_mode_put,
16ded525
TI
2392 },
2393 { } /* end */
2394};
e9edcee0 2395
e9edcee0
TI
2396/*
2397 * ALC880 ASUS W1V model
2398 *
2399 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2400 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2401 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2402 */
2403
2404/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2405static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2406 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2407 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2408 { } /* end */
2409};
2410
df694daa
KY
2411/* TCL S700 */
2412static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2413 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2414 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2415 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2417 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2420 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2421 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2422 { } /* end */
2423};
2424
ccc656ce
KY
2425/* Uniwill */
2426static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2427 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2428 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2429 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2430 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2443 {
2444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2445 .name = "Channel Mode",
2446 .info = alc_ch_mode_info,
2447 .get = alc_ch_mode_get,
2448 .put = alc_ch_mode_put,
2449 },
2450 { } /* end */
2451};
2452
2cf9f0fc
TD
2453static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2455 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2457 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2458 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2459 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2460 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2461 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2462 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2463 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2464 { } /* end */
2465};
2466
ccc656ce 2467static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2468 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2469 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2470 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2471 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2474 { } /* end */
2475};
2476
2134ea4f
TI
2477/*
2478 * virtual master controls
2479 */
2480
2481/*
2482 * slave controls for virtual master
2483 */
2484static const char *alc_slave_vols[] = {
2485 "Front Playback Volume",
2486 "Surround Playback Volume",
2487 "Center Playback Volume",
2488 "LFE Playback Volume",
2489 "Side Playback Volume",
2490 "Headphone Playback Volume",
2491 "Speaker Playback Volume",
2492 "Mono Playback Volume",
2134ea4f 2493 "Line-Out Playback Volume",
26f5df26 2494 "PCM Playback Volume",
2134ea4f
TI
2495 NULL,
2496};
2497
2498static const char *alc_slave_sws[] = {
2499 "Front Playback Switch",
2500 "Surround Playback Switch",
2501 "Center Playback Switch",
2502 "LFE Playback Switch",
2503 "Side Playback Switch",
2504 "Headphone Playback Switch",
2505 "Speaker Playback Switch",
2506 "Mono Playback Switch",
edb54a55 2507 "IEC958 Playback Switch",
23033b2b
TI
2508 "Line-Out Playback Switch",
2509 "PCM Playback Switch",
2134ea4f
TI
2510 NULL,
2511};
2512
1da177e4 2513/*
e9edcee0 2514 * build control elements
1da177e4 2515 */
603c4019 2516
5b0cb1d8
JK
2517#define NID_MAPPING (-1)
2518
2519#define SUBDEV_SPEAKER_ (0 << 6)
2520#define SUBDEV_HP_ (1 << 6)
2521#define SUBDEV_LINE_ (2 << 6)
2522#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2523#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2524#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2525
603c4019
TI
2526static void alc_free_kctls(struct hda_codec *codec);
2527
67d634c0 2528#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2529/* additional beep mixers; the actual parameters are overwritten at build */
2530static struct snd_kcontrol_new alc_beep_mixer[] = {
2531 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2532 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2533 { } /* end */
2534};
67d634c0 2535#endif
45bdd1c1 2536
1da177e4
LT
2537static int alc_build_controls(struct hda_codec *codec)
2538{
2539 struct alc_spec *spec = codec->spec;
5b0cb1d8
JK
2540 struct snd_kcontrol *kctl;
2541 struct snd_kcontrol_new *knew;
2542 int i, j, err;
2543 unsigned int u;
2544 hda_nid_t nid;
1da177e4
LT
2545
2546 for (i = 0; i < spec->num_mixers; i++) {
2547 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2548 if (err < 0)
2549 return err;
2550 }
f9e336f6
TI
2551 if (spec->cap_mixer) {
2552 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2553 if (err < 0)
2554 return err;
2555 }
1da177e4 2556 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2557 err = snd_hda_create_spdif_out_ctls(codec,
2558 spec->multiout.dig_out_nid);
1da177e4
LT
2559 if (err < 0)
2560 return err;
e64f14f4
TI
2561 if (!spec->no_analog) {
2562 err = snd_hda_create_spdif_share_sw(codec,
2563 &spec->multiout);
2564 if (err < 0)
2565 return err;
2566 spec->multiout.share_spdif = 1;
2567 }
1da177e4
LT
2568 }
2569 if (spec->dig_in_nid) {
2570 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2571 if (err < 0)
2572 return err;
2573 }
2134ea4f 2574
67d634c0 2575#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2576 /* create beep controls if needed */
2577 if (spec->beep_amp) {
2578 struct snd_kcontrol_new *knew;
2579 for (knew = alc_beep_mixer; knew->name; knew++) {
2580 struct snd_kcontrol *kctl;
2581 kctl = snd_ctl_new1(knew, codec);
2582 if (!kctl)
2583 return -ENOMEM;
2584 kctl->private_value = spec->beep_amp;
5e26dfd0 2585 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2586 if (err < 0)
2587 return err;
2588 }
2589 }
67d634c0 2590#endif
45bdd1c1 2591
2134ea4f 2592 /* if we have no master control, let's create it */
e64f14f4
TI
2593 if (!spec->no_analog &&
2594 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2595 unsigned int vmaster_tlv[4];
2134ea4f 2596 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2597 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2598 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2599 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2600 if (err < 0)
2601 return err;
2602 }
e64f14f4
TI
2603 if (!spec->no_analog &&
2604 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2605 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2606 NULL, alc_slave_sws);
2607 if (err < 0)
2608 return err;
2609 }
2610
5b0cb1d8
JK
2611 /* assign Capture Source enums to NID */
2612 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2613 if (!kctl)
2614 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2615 for (i = 0; kctl && i < kctl->count; i++) {
d1409ae4
TI
2616 hda_nid_t *nids = spec->capsrc_nids;
2617 if (!nids)
2618 nids = spec->adc_nids;
21949f00 2619 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
5b0cb1d8
JK
2620 if (err < 0)
2621 return err;
2622 }
2623 if (spec->cap_mixer) {
2624 const char *kname = kctl ? kctl->id.name : NULL;
2625 for (knew = spec->cap_mixer; knew->name; knew++) {
2626 if (kname && strcmp(knew->name, kname) == 0)
2627 continue;
2628 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2629 for (i = 0; kctl && i < kctl->count; i++) {
2630 err = snd_hda_add_nid(codec, kctl, i,
2631 spec->adc_nids[i]);
2632 if (err < 0)
2633 return err;
2634 }
2635 }
2636 }
2637
2638 /* other nid->control mapping */
2639 for (i = 0; i < spec->num_mixers; i++) {
2640 for (knew = spec->mixers[i]; knew->name; knew++) {
2641 if (knew->iface != NID_MAPPING)
2642 continue;
2643 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2644 if (kctl == NULL)
2645 continue;
2646 u = knew->subdevice;
2647 for (j = 0; j < 4; j++, u >>= 8) {
2648 nid = u & 0x3f;
2649 if (nid == 0)
2650 continue;
2651 switch (u & 0xc0) {
2652 case SUBDEV_SPEAKER_:
2653 nid = spec->autocfg.speaker_pins[nid];
2654 break;
2655 case SUBDEV_LINE_:
2656 nid = spec->autocfg.line_out_pins[nid];
2657 break;
2658 case SUBDEV_HP_:
2659 nid = spec->autocfg.hp_pins[nid];
2660 break;
2661 default:
2662 continue;
2663 }
2664 err = snd_hda_add_nid(codec, kctl, 0, nid);
2665 if (err < 0)
2666 return err;
2667 }
2668 u = knew->private_value;
2669 for (j = 0; j < 4; j++, u >>= 8) {
2670 nid = u & 0xff;
2671 if (nid == 0)
2672 continue;
2673 err = snd_hda_add_nid(codec, kctl, 0, nid);
2674 if (err < 0)
2675 return err;
2676 }
2677 }
2678 }
bae84e70
TI
2679
2680 alc_free_kctls(codec); /* no longer needed */
2681
1da177e4
LT
2682 return 0;
2683}
2684
e9edcee0 2685
1da177e4
LT
2686/*
2687 * initialize the codec volumes, etc
2688 */
2689
e9edcee0
TI
2690/*
2691 * generic initialization of ADC, input mixers and output mixers
2692 */
2693static struct hda_verb alc880_volume_init_verbs[] = {
2694 /*
2695 * Unmute ADC0-2 and set the default input to mic-in
2696 */
71fe7b82 2697 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2699 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2700 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2701 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2703
e9edcee0
TI
2704 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2705 * mixer widget
9c7f852e
TI
2706 * Note: PASD motherboards uses the Line In 2 as the input for front
2707 * panel mic (mic 2)
1da177e4 2708 */
e9edcee0 2709 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2717
e9edcee0
TI
2718 /*
2719 * Set up output mixers (0x0c - 0x0f)
1da177e4 2720 */
e9edcee0
TI
2721 /* set vol=0 to output mixers */
2722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2725 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2726 /* set up input amps for analog loopback */
2727 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2728 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2729 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2734 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2735 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2736
2737 { }
2738};
2739
e9edcee0
TI
2740/*
2741 * 3-stack pin configuration:
2742 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2743 */
2744static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2745 /*
2746 * preset connection lists of input pins
2747 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2748 */
2749 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2750 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2751 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2752
2753 /*
2754 * Set pin mode and muting
2755 */
2756 /* set front pin widgets 0x14 for output */
05acb863 2757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2760 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2761 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2762 /* Mic2 (as headphone out) for HP output */
2763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2765 /* Line In pin widget for input */
05acb863 2766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2767 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2768 /* Line2 (as front mic) pin widget for input and vref at 80% */
2769 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2770 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2771 /* CD pin widget for input */
05acb863 2772 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2773
e9edcee0
TI
2774 { }
2775};
1da177e4 2776
e9edcee0
TI
2777/*
2778 * 5-stack pin configuration:
2779 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2780 * line-in/side = 0x1a, f-mic = 0x1b
2781 */
2782static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2783 /*
2784 * preset connection lists of input pins
2785 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2786 */
e9edcee0
TI
2787 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2788 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2789
e9edcee0
TI
2790 /*
2791 * Set pin mode and muting
1da177e4 2792 */
e9edcee0
TI
2793 /* set pin widgets 0x14-0x17 for output */
2794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2796 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2797 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2798 /* unmute pins for output (no gain on this amp) */
2799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2803
2804 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2805 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2807 /* Mic2 (as headphone out) for HP output */
2808 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2809 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2810 /* Line In pin widget for input */
2811 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2812 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2813 /* Line2 (as front mic) pin widget for input and vref at 80% */
2814 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2815 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2816 /* CD pin widget for input */
2817 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2818
2819 { }
2820};
2821
e9edcee0
TI
2822/*
2823 * W810 pin configuration:
2824 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2825 */
2826static struct hda_verb alc880_pin_w810_init_verbs[] = {
2827 /* hphone/speaker input selector: front DAC */
2828 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2829
05acb863 2830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2833 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2835 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2836
e9edcee0 2837 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2838 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2839
1da177e4
LT
2840 { }
2841};
2842
e9edcee0
TI
2843/*
2844 * Z71V pin configuration:
2845 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2846 */
2847static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2852
16ded525 2853 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2855 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2856 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2857
2858 { }
2859};
2860
e9edcee0
TI
2861/*
2862 * 6-stack pin configuration:
9c7f852e
TI
2863 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2864 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2865 */
2866static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2867 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2868
16ded525 2869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2873 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2874 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2875 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2876 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2877
16ded525 2878 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2882 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2883 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2884 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2885 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2886 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2887
e9edcee0
TI
2888 { }
2889};
2890
ccc656ce
KY
2891/*
2892 * Uniwill pin configuration:
2893 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2894 * line = 0x1a
2895 */
2896static struct hda_verb alc880_uniwill_init_verbs[] = {
2897 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2898
2899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2900 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2902 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2903 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2904 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2905 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2906 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2907 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2913
2914 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2917 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2918 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2920 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2921 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2922 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2923
2924 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2925 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2926
2927 { }
2928};
2929
2930/*
2931* Uniwill P53
ea1fb29a 2932* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2933 */
2934static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2935 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2936
2937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2938 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2941 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2942 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2945 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2947 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2948 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2949
2950 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2951 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2952 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2953 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2954 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2955 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2956
2957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2958 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2959
2960 { }
2961};
2962
2cf9f0fc
TD
2963static struct hda_verb alc880_beep_init_verbs[] = {
2964 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2965 { }
2966};
2967
458a4fab
TI
2968/* auto-toggle front mic */
2969static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2970{
2971 unsigned int present;
2972 unsigned char bits;
ccc656ce 2973
864f92be 2974 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
2975 bits = present ? HDA_AMP_MUTE : 0;
2976 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2977}
2978
4f5d1706 2979static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 2980{
a9fd4f3f
TI
2981 struct alc_spec *spec = codec->spec;
2982
2983 spec->autocfg.hp_pins[0] = 0x14;
2984 spec->autocfg.speaker_pins[0] = 0x15;
2985 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
2986}
2987
2988static void alc880_uniwill_init_hook(struct hda_codec *codec)
2989{
a9fd4f3f 2990 alc_automute_amp(codec);
458a4fab 2991 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2992}
2993
2994static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2995 unsigned int res)
2996{
2997 /* Looks like the unsol event is incompatible with the standard
2998 * definition. 4bit tag is placed at 28 bit!
2999 */
458a4fab 3000 switch (res >> 28) {
458a4fab
TI
3001 case ALC880_MIC_EVENT:
3002 alc880_uniwill_mic_automute(codec);
3003 break;
a9fd4f3f
TI
3004 default:
3005 alc_automute_amp_unsol_event(codec, res);
3006 break;
458a4fab 3007 }
ccc656ce
KY
3008}
3009
4f5d1706 3010static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3011{
a9fd4f3f 3012 struct alc_spec *spec = codec->spec;
ccc656ce 3013
a9fd4f3f
TI
3014 spec->autocfg.hp_pins[0] = 0x14;
3015 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3016}
3017
3018static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3019{
3020 unsigned int present;
ea1fb29a 3021
ccc656ce 3022 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3023 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3024 present &= HDA_AMP_VOLMASK;
3025 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3026 HDA_AMP_VOLMASK, present);
3027 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3028 HDA_AMP_VOLMASK, present);
ccc656ce 3029}
47fd830a 3030
ccc656ce
KY
3031static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3032 unsigned int res)
3033{
3034 /* Looks like the unsol event is incompatible with the standard
3035 * definition. 4bit tag is placed at 28 bit!
3036 */
f12ab1e0 3037 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3038 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3039 else
3040 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3041}
3042
e9edcee0
TI
3043/*
3044 * F1734 pin configuration:
3045 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3046 */
3047static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3048 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3049 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3050 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3051 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3053
e9edcee0 3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3058
e9edcee0
TI
3059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3061 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3062 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3063 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3064 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3065 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3066 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3067 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3068
937b4160
TI
3069 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3070 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3071
dfc0ff62
TI
3072 { }
3073};
3074
e9edcee0
TI
3075/*
3076 * ASUS pin configuration:
3077 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3078 */
3079static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3080 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3081 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3082 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3083 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3084
3085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3090 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3091 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3093
3094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3095 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3096 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3097 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3098 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3099 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3102 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3103
e9edcee0
TI
3104 { }
3105};
16ded525 3106
e9edcee0 3107/* Enable GPIO mask and set output */
bc9f98a9
KY
3108#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3109#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3110#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3111
3112/* Clevo m520g init */
3113static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3114 /* headphone output */
3115 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3116 /* line-out */
3117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3119 /* Line-in */
3120 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3121 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3122 /* CD */
3123 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3124 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3125 /* Mic1 (rear panel) */
3126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3127 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3128 /* Mic2 (front panel) */
3129 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3130 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3131 /* headphone */
3132 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3134 /* change to EAPD mode */
3135 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3136 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3137
3138 { }
16ded525
TI
3139};
3140
df694daa 3141static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3142 /* change to EAPD mode */
3143 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3144 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3145
df694daa
KY
3146 /* Headphone output */
3147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3148 /* Front output*/
3149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3150 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3151
3152 /* Line In pin widget for input */
3153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3154 /* CD pin widget for input */
3155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3156 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3158
3159 /* change to EAPD mode */
3160 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3161 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3162
3163 { }
3164};
16ded525 3165
e9edcee0 3166/*
ae6b813a
TI
3167 * LG m1 express dual
3168 *
3169 * Pin assignment:
3170 * Rear Line-In/Out (blue): 0x14
3171 * Build-in Mic-In: 0x15
3172 * Speaker-out: 0x17
3173 * HP-Out (green): 0x1b
3174 * Mic-In/Out (red): 0x19
3175 * SPDIF-Out: 0x1e
3176 */
3177
3178/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3179static hda_nid_t alc880_lg_dac_nids[3] = {
3180 0x05, 0x02, 0x03
3181};
3182
3183/* seems analog CD is not working */
3184static struct hda_input_mux alc880_lg_capture_source = {
3185 .num_items = 3,
3186 .items = {
3187 { "Mic", 0x1 },
3188 { "Line", 0x5 },
3189 { "Internal Mic", 0x6 },
3190 },
3191};
3192
3193/* 2,4,6 channel modes */
3194static struct hda_verb alc880_lg_ch2_init[] = {
3195 /* set line-in and mic-in to input */
3196 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3197 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3198 { }
3199};
3200
3201static struct hda_verb alc880_lg_ch4_init[] = {
3202 /* set line-in to out and mic-in to input */
3203 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3204 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3205 { }
3206};
3207
3208static struct hda_verb alc880_lg_ch6_init[] = {
3209 /* set line-in and mic-in to output */
3210 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3211 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3212 { }
3213};
3214
3215static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3216 { 2, alc880_lg_ch2_init },
3217 { 4, alc880_lg_ch4_init },
3218 { 6, alc880_lg_ch6_init },
3219};
3220
3221static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3223 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3225 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3226 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3227 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3228 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3229 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3233 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3234 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3235 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3236 {
3237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3238 .name = "Channel Mode",
3239 .info = alc_ch_mode_info,
3240 .get = alc_ch_mode_get,
3241 .put = alc_ch_mode_put,
3242 },
3243 { } /* end */
3244};
3245
3246static struct hda_verb alc880_lg_init_verbs[] = {
3247 /* set capture source to mic-in */
3248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3250 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3251 /* mute all amp mixer inputs */
3252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3255 /* line-in to input */
3256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3258 /* built-in mic */
3259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3261 /* speaker-out */
3262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3264 /* mic-in to input */
3265 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3266 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3267 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3268 /* HP-out */
3269 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3271 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3272 /* jack sense */
a9fd4f3f 3273 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3274 { }
3275};
3276
3277/* toggle speaker-output according to the hp-jack state */
4f5d1706 3278static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3279{
a9fd4f3f 3280 struct alc_spec *spec = codec->spec;
ae6b813a 3281
a9fd4f3f
TI
3282 spec->autocfg.hp_pins[0] = 0x1b;
3283 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3284}
3285
d681518a
TI
3286/*
3287 * LG LW20
3288 *
3289 * Pin assignment:
3290 * Speaker-out: 0x14
3291 * Mic-In: 0x18
e4f41da9
CM
3292 * Built-in Mic-In: 0x19
3293 * Line-In: 0x1b
3294 * HP-Out: 0x1a
d681518a
TI
3295 * SPDIF-Out: 0x1e
3296 */
3297
d681518a 3298static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3299 .num_items = 3,
d681518a
TI
3300 .items = {
3301 { "Mic", 0x0 },
3302 { "Internal Mic", 0x1 },
e4f41da9 3303 { "Line In", 0x2 },
d681518a
TI
3304 },
3305};
3306
0a8c5da3
CM
3307#define alc880_lg_lw_modes alc880_threestack_modes
3308
d681518a 3309static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3310 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3312 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3313 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3314 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3315 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3316 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3317 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3318 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3319 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3322 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3323 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3324 {
3325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3326 .name = "Channel Mode",
3327 .info = alc_ch_mode_info,
3328 .get = alc_ch_mode_get,
3329 .put = alc_ch_mode_put,
3330 },
d681518a
TI
3331 { } /* end */
3332};
3333
3334static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3335 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3336 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3337 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3338
d681518a
TI
3339 /* set capture source to mic-in */
3340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3341 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3342 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3344 /* speaker-out */
3345 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3346 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3347 /* HP-out */
d681518a
TI
3348 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3349 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3350 /* mic-in to input */
3351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3353 /* built-in mic */
3354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3355 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3356 /* jack sense */
a9fd4f3f 3357 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3358 { }
3359};
3360
3361/* toggle speaker-output according to the hp-jack state */
4f5d1706 3362static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3363{
a9fd4f3f 3364 struct alc_spec *spec = codec->spec;
d681518a 3365
a9fd4f3f
TI
3366 spec->autocfg.hp_pins[0] = 0x1b;
3367 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3368}
3369
df99cd33
TI
3370static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3371 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3372 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3375 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3376 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3377 { } /* end */
3378};
3379
3380static struct hda_input_mux alc880_medion_rim_capture_source = {
3381 .num_items = 2,
3382 .items = {
3383 { "Mic", 0x0 },
3384 { "Internal Mic", 0x1 },
3385 },
3386};
3387
3388static struct hda_verb alc880_medion_rim_init_verbs[] = {
3389 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3390
3391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3393
3394 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3397 /* Mic2 (as headphone out) for HP output */
3398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3400 /* Internal Speaker */
3401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3403
3404 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3405 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3406
3407 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3408 { }
3409};
3410
3411/* toggle speaker-output according to the hp-jack state */
3412static void alc880_medion_rim_automute(struct hda_codec *codec)
3413{
a9fd4f3f
TI
3414 struct alc_spec *spec = codec->spec;
3415 alc_automute_amp(codec);
3416 /* toggle EAPD */
3417 if (spec->jack_present)
df99cd33
TI
3418 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3419 else
3420 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3421}
3422
3423static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3424 unsigned int res)
3425{
3426 /* Looks like the unsol event is incompatible with the standard
3427 * definition. 4bit tag is placed at 28 bit!
3428 */
3429 if ((res >> 28) == ALC880_HP_EVENT)
3430 alc880_medion_rim_automute(codec);
3431}
3432
4f5d1706 3433static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3434{
3435 struct alc_spec *spec = codec->spec;
3436
3437 spec->autocfg.hp_pins[0] = 0x14;
3438 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3439}
3440
cb53c626
TI
3441#ifdef CONFIG_SND_HDA_POWER_SAVE
3442static struct hda_amp_list alc880_loopbacks[] = {
3443 { 0x0b, HDA_INPUT, 0 },
3444 { 0x0b, HDA_INPUT, 1 },
3445 { 0x0b, HDA_INPUT, 2 },
3446 { 0x0b, HDA_INPUT, 3 },
3447 { 0x0b, HDA_INPUT, 4 },
3448 { } /* end */
3449};
3450
3451static struct hda_amp_list alc880_lg_loopbacks[] = {
3452 { 0x0b, HDA_INPUT, 1 },
3453 { 0x0b, HDA_INPUT, 6 },
3454 { 0x0b, HDA_INPUT, 7 },
3455 { } /* end */
3456};
3457#endif
3458
ae6b813a
TI
3459/*
3460 * Common callbacks
e9edcee0
TI
3461 */
3462
1da177e4
LT
3463static int alc_init(struct hda_codec *codec)
3464{
3465 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3466 unsigned int i;
3467
2c3bf9ab 3468 alc_fix_pll(codec);
4a79ba34 3469 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3470
e9edcee0
TI
3471 for (i = 0; i < spec->num_init_verbs; i++)
3472 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3473
3474 if (spec->init_hook)
3475 spec->init_hook(codec);
3476
ad35879a
TI
3477#ifdef CONFIG_SND_HDA_POWER_SAVE
3478 if (codec->patch_ops.check_power_status)
3479 codec->patch_ops.check_power_status(codec, 0x01);
3480#endif
1da177e4
LT
3481 return 0;
3482}
3483
ae6b813a
TI
3484static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3485{
3486 struct alc_spec *spec = codec->spec;
3487
3488 if (spec->unsol_event)
3489 spec->unsol_event(codec, res);
3490}
3491
cb53c626
TI
3492#ifdef CONFIG_SND_HDA_POWER_SAVE
3493static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3494{
3495 struct alc_spec *spec = codec->spec;
3496 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3497}
3498#endif
3499
1da177e4
LT
3500/*
3501 * Analog playback callbacks
3502 */
3503static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3504 struct hda_codec *codec,
c8b6bf9b 3505 struct snd_pcm_substream *substream)
1da177e4
LT
3506{
3507 struct alc_spec *spec = codec->spec;
9a08160b
TI
3508 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3509 hinfo);
1da177e4
LT
3510}
3511
3512static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3513 struct hda_codec *codec,
3514 unsigned int stream_tag,
3515 unsigned int format,
c8b6bf9b 3516 struct snd_pcm_substream *substream)
1da177e4
LT
3517{
3518 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3519 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3520 stream_tag, format, substream);
1da177e4
LT
3521}
3522
3523static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3524 struct hda_codec *codec,
c8b6bf9b 3525 struct snd_pcm_substream *substream)
1da177e4
LT
3526{
3527 struct alc_spec *spec = codec->spec;
3528 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3529}
3530
3531/*
3532 * Digital out
3533 */
3534static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3535 struct hda_codec *codec,
c8b6bf9b 3536 struct snd_pcm_substream *substream)
1da177e4
LT
3537{
3538 struct alc_spec *spec = codec->spec;
3539 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3540}
3541
6b97eb45
TI
3542static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3543 struct hda_codec *codec,
3544 unsigned int stream_tag,
3545 unsigned int format,
3546 struct snd_pcm_substream *substream)
3547{
3548 struct alc_spec *spec = codec->spec;
3549 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3550 stream_tag, format, substream);
3551}
3552
9b5f12e5
TI
3553static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3554 struct hda_codec *codec,
3555 struct snd_pcm_substream *substream)
3556{
3557 struct alc_spec *spec = codec->spec;
3558 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3559}
3560
1da177e4
LT
3561static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3562 struct hda_codec *codec,
c8b6bf9b 3563 struct snd_pcm_substream *substream)
1da177e4
LT
3564{
3565 struct alc_spec *spec = codec->spec;
3566 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3567}
3568
3569/*
3570 * Analog capture
3571 */
6330079f 3572static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3573 struct hda_codec *codec,
3574 unsigned int stream_tag,
3575 unsigned int format,
c8b6bf9b 3576 struct snd_pcm_substream *substream)
1da177e4
LT
3577{
3578 struct alc_spec *spec = codec->spec;
3579
6330079f 3580 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3581 stream_tag, 0, format);
3582 return 0;
3583}
3584
6330079f 3585static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3586 struct hda_codec *codec,
c8b6bf9b 3587 struct snd_pcm_substream *substream)
1da177e4
LT
3588{
3589 struct alc_spec *spec = codec->spec;
3590
888afa15
TI
3591 snd_hda_codec_cleanup_stream(codec,
3592 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3593 return 0;
3594}
3595
3596
3597/*
3598 */
3599static struct hda_pcm_stream alc880_pcm_analog_playback = {
3600 .substreams = 1,
3601 .channels_min = 2,
3602 .channels_max = 8,
e9edcee0 3603 /* NID is set in alc_build_pcms */
1da177e4
LT
3604 .ops = {
3605 .open = alc880_playback_pcm_open,
3606 .prepare = alc880_playback_pcm_prepare,
3607 .cleanup = alc880_playback_pcm_cleanup
3608 },
3609};
3610
3611static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
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_playback = {
3619 .substreams = 1,
3620 .channels_min = 2,
3621 .channels_max = 2,
3622 /* NID is set in alc_build_pcms */
3623};
3624
3625static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3626 .substreams = 2, /* can be overridden */
1da177e4
LT
3627 .channels_min = 2,
3628 .channels_max = 2,
e9edcee0 3629 /* NID is set in alc_build_pcms */
1da177e4 3630 .ops = {
6330079f
TI
3631 .prepare = alc880_alt_capture_pcm_prepare,
3632 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3633 },
3634};
3635
3636static struct hda_pcm_stream alc880_pcm_digital_playback = {
3637 .substreams = 1,
3638 .channels_min = 2,
3639 .channels_max = 2,
3640 /* NID is set in alc_build_pcms */
3641 .ops = {
3642 .open = alc880_dig_playback_pcm_open,
6b97eb45 3643 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3644 .prepare = alc880_dig_playback_pcm_prepare,
3645 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3646 },
3647};
3648
3649static struct hda_pcm_stream alc880_pcm_digital_capture = {
3650 .substreams = 1,
3651 .channels_min = 2,
3652 .channels_max = 2,
3653 /* NID is set in alc_build_pcms */
3654};
3655
4c5186ed 3656/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3657static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3658 .substreams = 0,
3659 .channels_min = 0,
3660 .channels_max = 0,
3661};
3662
1da177e4
LT
3663static int alc_build_pcms(struct hda_codec *codec)
3664{
3665 struct alc_spec *spec = codec->spec;
3666 struct hda_pcm *info = spec->pcm_rec;
3667 int i;
3668
3669 codec->num_pcms = 1;
3670 codec->pcm_info = info;
3671
e64f14f4
TI
3672 if (spec->no_analog)
3673 goto skip_analog;
3674
812a2cca
TI
3675 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3676 "%s Analog", codec->chip_name);
1da177e4 3677 info->name = spec->stream_name_analog;
274693f3 3678
4a471b7d 3679 if (spec->stream_analog_playback) {
da3cec35
TI
3680 if (snd_BUG_ON(!spec->multiout.dac_nids))
3681 return -EINVAL;
4a471b7d
TI
3682 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3683 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3684 }
3685 if (spec->stream_analog_capture) {
da3cec35
TI
3686 if (snd_BUG_ON(!spec->adc_nids))
3687 return -EINVAL;
4a471b7d
TI
3688 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3689 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3690 }
3691
3692 if (spec->channel_mode) {
3693 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3694 for (i = 0; i < spec->num_channel_mode; i++) {
3695 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3696 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3697 }
1da177e4
LT
3698 }
3699 }
3700
e64f14f4 3701 skip_analog:
e08a007d 3702 /* SPDIF for stream index #1 */
1da177e4 3703 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3704 snprintf(spec->stream_name_digital,
3705 sizeof(spec->stream_name_digital),
3706 "%s Digital", codec->chip_name);
e08a007d 3707 codec->num_pcms = 2;
b25c9da1 3708 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3709 info = spec->pcm_rec + 1;
1da177e4 3710 info->name = spec->stream_name_digital;
8c441982
TI
3711 if (spec->dig_out_type)
3712 info->pcm_type = spec->dig_out_type;
3713 else
3714 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3715 if (spec->multiout.dig_out_nid &&
3716 spec->stream_digital_playback) {
1da177e4
LT
3717 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3718 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3719 }
4a471b7d
TI
3720 if (spec->dig_in_nid &&
3721 spec->stream_digital_capture) {
1da177e4
LT
3722 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3723 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3724 }
963f803f
TI
3725 /* FIXME: do we need this for all Realtek codec models? */
3726 codec->spdif_status_reset = 1;
1da177e4
LT
3727 }
3728
e64f14f4
TI
3729 if (spec->no_analog)
3730 return 0;
3731
e08a007d
TI
3732 /* If the use of more than one ADC is requested for the current
3733 * model, configure a second analog capture-only PCM.
3734 */
3735 /* Additional Analaog capture for index #2 */
6330079f
TI
3736 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3737 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3738 codec->num_pcms = 3;
c06134d7 3739 info = spec->pcm_rec + 2;
e08a007d 3740 info->name = spec->stream_name_analog;
6330079f
TI
3741 if (spec->alt_dac_nid) {
3742 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3743 *spec->stream_analog_alt_playback;
3744 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3745 spec->alt_dac_nid;
3746 } else {
3747 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3748 alc_pcm_null_stream;
3749 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3750 }
3751 if (spec->num_adc_nids > 1) {
3752 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3753 *spec->stream_analog_alt_capture;
3754 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3755 spec->adc_nids[1];
3756 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3757 spec->num_adc_nids - 1;
3758 } else {
3759 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3760 alc_pcm_null_stream;
3761 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3762 }
3763 }
3764
1da177e4
LT
3765 return 0;
3766}
3767
a4e09aa3
TI
3768static inline void alc_shutup(struct hda_codec *codec)
3769{
3770 snd_hda_shutup_pins(codec);
3771}
3772
603c4019
TI
3773static void alc_free_kctls(struct hda_codec *codec)
3774{
3775 struct alc_spec *spec = codec->spec;
3776
3777 if (spec->kctls.list) {
3778 struct snd_kcontrol_new *kctl = spec->kctls.list;
3779 int i;
3780 for (i = 0; i < spec->kctls.used; i++)
3781 kfree(kctl[i].name);
3782 }
3783 snd_array_free(&spec->kctls);
3784}
3785
1da177e4
LT
3786static void alc_free(struct hda_codec *codec)
3787{
e9edcee0 3788 struct alc_spec *spec = codec->spec;
e9edcee0 3789
f12ab1e0 3790 if (!spec)
e9edcee0
TI
3791 return;
3792
a4e09aa3 3793 alc_shutup(codec);
603c4019 3794 alc_free_kctls(codec);
e9edcee0 3795 kfree(spec);
680cd536 3796 snd_hda_detach_beep_device(codec);
1da177e4
LT
3797}
3798
f5de24b0 3799#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3800static void alc_power_eapd(struct hda_codec *codec)
3801{
3802 /* We currently only handle front, HP */
3803 switch (codec->vendor_id) {
3804 case 0x10ec0260:
9e4c8496
TI
3805 set_eapd(codec, 0x0f, 0);
3806 set_eapd(codec, 0x10, 0);
c97259df
DC
3807 break;
3808 case 0x10ec0262:
3809 case 0x10ec0267:
3810 case 0x10ec0268:
3811 case 0x10ec0269:
9e4c8496 3812 case 0x10ec0270:
c97259df
DC
3813 case 0x10ec0272:
3814 case 0x10ec0660:
3815 case 0x10ec0662:
3816 case 0x10ec0663:
3817 case 0x10ec0862:
3818 case 0x10ec0889:
9e4c8496
TI
3819 set_eapd(codec, 0x14, 0);
3820 set_eapd(codec, 0x15, 0);
c97259df
DC
3821 break;
3822 }
3823}
3824
f5de24b0
HM
3825static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3826{
3827 struct alc_spec *spec = codec->spec;
a4e09aa3 3828 alc_shutup(codec);
f5de24b0 3829 if (spec && spec->power_hook)
c97259df 3830 spec->power_hook(codec);
f5de24b0
HM
3831 return 0;
3832}
3833#endif
3834
e044c39a 3835#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3836static int alc_resume(struct hda_codec *codec)
3837{
e044c39a
TI
3838 codec->patch_ops.init(codec);
3839 snd_hda_codec_resume_amp(codec);
3840 snd_hda_codec_resume_cache(codec);
ad35879a
TI
3841#ifdef CONFIG_SND_HDA_POWER_SAVE
3842 if (codec->patch_ops.check_power_status)
3843 codec->patch_ops.check_power_status(codec, 0x01);
3844#endif
e044c39a
TI
3845 return 0;
3846}
e044c39a
TI
3847#endif
3848
1da177e4
LT
3849/*
3850 */
3851static struct hda_codec_ops alc_patch_ops = {
3852 .build_controls = alc_build_controls,
3853 .build_pcms = alc_build_pcms,
3854 .init = alc_init,
3855 .free = alc_free,
ae6b813a 3856 .unsol_event = alc_unsol_event,
e044c39a
TI
3857#ifdef SND_HDA_NEEDS_RESUME
3858 .resume = alc_resume,
3859#endif
cb53c626 3860#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 3861 .suspend = alc_suspend,
cb53c626
TI
3862 .check_power_status = alc_check_power_status,
3863#endif
c97259df 3864 .reboot_notify = alc_shutup,
1da177e4
LT
3865};
3866
c027ddcd
KY
3867/* replace the codec chip_name with the given string */
3868static int alc_codec_rename(struct hda_codec *codec, const char *name)
3869{
3870 kfree(codec->chip_name);
3871 codec->chip_name = kstrdup(name, GFP_KERNEL);
3872 if (!codec->chip_name) {
3873 alc_free(codec);
3874 return -ENOMEM;
3875 }
3876 return 0;
3877}
3878
2fa522be
TI
3879/*
3880 * Test configuration for debugging
3881 *
3882 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3883 * enum controls.
3884 */
3885#ifdef CONFIG_SND_DEBUG
3886static hda_nid_t alc880_test_dac_nids[4] = {
3887 0x02, 0x03, 0x04, 0x05
3888};
3889
3890static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3891 .num_items = 7,
2fa522be
TI
3892 .items = {
3893 { "In-1", 0x0 },
3894 { "In-2", 0x1 },
3895 { "In-3", 0x2 },
3896 { "In-4", 0x3 },
3897 { "CD", 0x4 },
ae6b813a
TI
3898 { "Front", 0x5 },
3899 { "Surround", 0x6 },
2fa522be
TI
3900 },
3901};
3902
d2a6d7dc 3903static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3904 { 2, NULL },
fd2c326d 3905 { 4, NULL },
2fa522be 3906 { 6, NULL },
fd2c326d 3907 { 8, NULL },
2fa522be
TI
3908};
3909
9c7f852e
TI
3910static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3911 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3912{
3913 static char *texts[] = {
3914 "N/A", "Line Out", "HP Out",
3915 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3916 };
3917 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3918 uinfo->count = 1;
3919 uinfo->value.enumerated.items = 8;
3920 if (uinfo->value.enumerated.item >= 8)
3921 uinfo->value.enumerated.item = 7;
3922 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3923 return 0;
3924}
3925
9c7f852e
TI
3926static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3927 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3928{
3929 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3930 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3931 unsigned int pin_ctl, item = 0;
3932
3933 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3934 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3935 if (pin_ctl & AC_PINCTL_OUT_EN) {
3936 if (pin_ctl & AC_PINCTL_HP_EN)
3937 item = 2;
3938 else
3939 item = 1;
3940 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3941 switch (pin_ctl & AC_PINCTL_VREFEN) {
3942 case AC_PINCTL_VREF_HIZ: item = 3; break;
3943 case AC_PINCTL_VREF_50: item = 4; break;
3944 case AC_PINCTL_VREF_GRD: item = 5; break;
3945 case AC_PINCTL_VREF_80: item = 6; break;
3946 case AC_PINCTL_VREF_100: item = 7; break;
3947 }
3948 }
3949 ucontrol->value.enumerated.item[0] = item;
3950 return 0;
3951}
3952
9c7f852e
TI
3953static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3954 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3955{
3956 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3957 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3958 static unsigned int ctls[] = {
3959 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3960 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3961 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3962 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3963 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3964 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3965 };
3966 unsigned int old_ctl, new_ctl;
3967
3968 old_ctl = snd_hda_codec_read(codec, nid, 0,
3969 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3970 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3971 if (old_ctl != new_ctl) {
82beb8fd
TI
3972 int val;
3973 snd_hda_codec_write_cache(codec, nid, 0,
3974 AC_VERB_SET_PIN_WIDGET_CONTROL,
3975 new_ctl);
47fd830a
TI
3976 val = ucontrol->value.enumerated.item[0] >= 3 ?
3977 HDA_AMP_MUTE : 0;
3978 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3979 HDA_AMP_MUTE, val);
2fa522be
TI
3980 return 1;
3981 }
3982 return 0;
3983}
3984
9c7f852e
TI
3985static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3986 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3987{
3988 static char *texts[] = {
3989 "Front", "Surround", "CLFE", "Side"
3990 };
3991 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3992 uinfo->count = 1;
3993 uinfo->value.enumerated.items = 4;
3994 if (uinfo->value.enumerated.item >= 4)
3995 uinfo->value.enumerated.item = 3;
3996 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3997 return 0;
3998}
3999
9c7f852e
TI
4000static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4001 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4002{
4003 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4004 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4005 unsigned int sel;
4006
4007 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4008 ucontrol->value.enumerated.item[0] = sel & 3;
4009 return 0;
4010}
4011
9c7f852e
TI
4012static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4013 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4014{
4015 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4016 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4017 unsigned int sel;
4018
4019 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4020 if (ucontrol->value.enumerated.item[0] != sel) {
4021 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4022 snd_hda_codec_write_cache(codec, nid, 0,
4023 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4024 return 1;
4025 }
4026 return 0;
4027}
4028
4029#define PIN_CTL_TEST(xname,nid) { \
4030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4031 .name = xname, \
5b0cb1d8 4032 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4033 .info = alc_test_pin_ctl_info, \
4034 .get = alc_test_pin_ctl_get, \
4035 .put = alc_test_pin_ctl_put, \
4036 .private_value = nid \
4037 }
4038
4039#define PIN_SRC_TEST(xname,nid) { \
4040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4041 .name = xname, \
5b0cb1d8 4042 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4043 .info = alc_test_pin_src_info, \
4044 .get = alc_test_pin_src_get, \
4045 .put = alc_test_pin_src_put, \
4046 .private_value = nid \
4047 }
4048
c8b6bf9b 4049static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4051 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4052 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4053 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4055 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4056 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4057 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4058 PIN_CTL_TEST("Front Pin Mode", 0x14),
4059 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4060 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4061 PIN_CTL_TEST("Side Pin Mode", 0x17),
4062 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4063 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4064 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4065 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4066 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4067 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4068 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4069 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4070 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4071 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4072 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4073 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4074 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4075 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4076 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4077 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4078 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4079 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4080 {
4081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4082 .name = "Channel Mode",
df694daa
KY
4083 .info = alc_ch_mode_info,
4084 .get = alc_ch_mode_get,
4085 .put = alc_ch_mode_put,
2fa522be
TI
4086 },
4087 { } /* end */
4088};
4089
4090static struct hda_verb alc880_test_init_verbs[] = {
4091 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4094 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4095 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4096 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4097 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4098 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4099 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4100 /* Vol output for 0x0c-0x0f */
05acb863
TI
4101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4105 /* Set output pins 0x14-0x17 */
05acb863
TI
4106 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4109 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4110 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4111 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4113 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4114 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4115 /* Set input pins 0x18-0x1c */
16ded525
TI
4116 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4117 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4121 /* Mute input pins 0x18-0x1b */
05acb863
TI
4122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4124 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4125 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4126 /* ADC set up */
05acb863 4127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4128 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4129 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4130 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4131 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4132 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4133 /* Analog input/passthru */
4134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4139 { }
4140};
4141#endif
4142
1da177e4
LT
4143/*
4144 */
4145
f5fcc13c
TI
4146static const char *alc880_models[ALC880_MODEL_LAST] = {
4147 [ALC880_3ST] = "3stack",
4148 [ALC880_TCL_S700] = "tcl",
4149 [ALC880_3ST_DIG] = "3stack-digout",
4150 [ALC880_CLEVO] = "clevo",
4151 [ALC880_5ST] = "5stack",
4152 [ALC880_5ST_DIG] = "5stack-digout",
4153 [ALC880_W810] = "w810",
4154 [ALC880_Z71V] = "z71v",
4155 [ALC880_6ST] = "6stack",
4156 [ALC880_6ST_DIG] = "6stack-digout",
4157 [ALC880_ASUS] = "asus",
4158 [ALC880_ASUS_W1V] = "asus-w1v",
4159 [ALC880_ASUS_DIG] = "asus-dig",
4160 [ALC880_ASUS_DIG2] = "asus-dig2",
4161 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4162 [ALC880_UNIWILL_P53] = "uniwill-p53",
4163 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4164 [ALC880_F1734] = "F1734",
4165 [ALC880_LG] = "lg",
4166 [ALC880_LG_LW] = "lg-lw",
df99cd33 4167 [ALC880_MEDION_RIM] = "medion",
2fa522be 4168#ifdef CONFIG_SND_DEBUG
f5fcc13c 4169 [ALC880_TEST] = "test",
2fa522be 4170#endif
f5fcc13c
TI
4171 [ALC880_AUTO] = "auto",
4172};
4173
4174static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4175 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4176 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4177 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4178 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4179 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4180 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4181 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4182 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4183 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4184 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4185 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4186 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4187 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4188 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4189 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4190 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4191 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4192 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4193 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4194 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4195 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4196 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4197 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4198 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4199 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4200 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4201 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4202 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4203 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4204 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4205 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4206 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4207 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4208 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4209 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4210 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4211 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4212 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4213 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4214 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4215 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4216 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4217 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4218 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4219 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4220 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4221 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4222 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4223 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 4224 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 4225 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4226 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4227 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4228 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4229 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4230 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4231 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4232 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4233 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4234 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4235 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4236 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4237 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4238 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4239 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4240 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4241 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4242 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4243 /* default Intel */
4244 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4245 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4246 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4247 {}
4248};
4249
16ded525 4250/*
df694daa 4251 * ALC880 codec presets
16ded525 4252 */
16ded525
TI
4253static struct alc_config_preset alc880_presets[] = {
4254 [ALC880_3ST] = {
e9edcee0 4255 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4256 .init_verbs = { alc880_volume_init_verbs,
4257 alc880_pin_3stack_init_verbs },
16ded525 4258 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4259 .dac_nids = alc880_dac_nids,
16ded525
TI
4260 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4261 .channel_mode = alc880_threestack_modes,
4e195a7b 4262 .need_dac_fix = 1,
16ded525
TI
4263 .input_mux = &alc880_capture_source,
4264 },
4265 [ALC880_3ST_DIG] = {
e9edcee0 4266 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4267 .init_verbs = { alc880_volume_init_verbs,
4268 alc880_pin_3stack_init_verbs },
16ded525 4269 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4270 .dac_nids = alc880_dac_nids,
4271 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4272 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4273 .channel_mode = alc880_threestack_modes,
4e195a7b 4274 .need_dac_fix = 1,
16ded525
TI
4275 .input_mux = &alc880_capture_source,
4276 },
df694daa
KY
4277 [ALC880_TCL_S700] = {
4278 .mixers = { alc880_tcl_s700_mixer },
4279 .init_verbs = { alc880_volume_init_verbs,
4280 alc880_pin_tcl_S700_init_verbs,
4281 alc880_gpio2_init_verbs },
4282 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4283 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4284 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4285 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4286 .hp_nid = 0x03,
4287 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4288 .channel_mode = alc880_2_jack_modes,
4289 .input_mux = &alc880_capture_source,
4290 },
16ded525 4291 [ALC880_5ST] = {
f12ab1e0
TI
4292 .mixers = { alc880_three_stack_mixer,
4293 alc880_five_stack_mixer},
4294 .init_verbs = { alc880_volume_init_verbs,
4295 alc880_pin_5stack_init_verbs },
16ded525
TI
4296 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4297 .dac_nids = alc880_dac_nids,
16ded525
TI
4298 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4299 .channel_mode = alc880_fivestack_modes,
4300 .input_mux = &alc880_capture_source,
4301 },
4302 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4303 .mixers = { alc880_three_stack_mixer,
4304 alc880_five_stack_mixer },
4305 .init_verbs = { alc880_volume_init_verbs,
4306 alc880_pin_5stack_init_verbs },
16ded525
TI
4307 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4308 .dac_nids = alc880_dac_nids,
4309 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4310 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4311 .channel_mode = alc880_fivestack_modes,
4312 .input_mux = &alc880_capture_source,
4313 },
b6482d48
TI
4314 [ALC880_6ST] = {
4315 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4316 .init_verbs = { alc880_volume_init_verbs,
4317 alc880_pin_6stack_init_verbs },
b6482d48
TI
4318 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4319 .dac_nids = alc880_6st_dac_nids,
4320 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4321 .channel_mode = alc880_sixstack_modes,
4322 .input_mux = &alc880_6stack_capture_source,
4323 },
16ded525 4324 [ALC880_6ST_DIG] = {
e9edcee0 4325 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4326 .init_verbs = { alc880_volume_init_verbs,
4327 alc880_pin_6stack_init_verbs },
16ded525
TI
4328 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4329 .dac_nids = alc880_6st_dac_nids,
4330 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4331 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4332 .channel_mode = alc880_sixstack_modes,
4333 .input_mux = &alc880_6stack_capture_source,
4334 },
4335 [ALC880_W810] = {
e9edcee0 4336 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4337 .init_verbs = { alc880_volume_init_verbs,
4338 alc880_pin_w810_init_verbs,
b0af0de5 4339 alc880_gpio2_init_verbs },
16ded525
TI
4340 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4341 .dac_nids = alc880_w810_dac_nids,
4342 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4343 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4344 .channel_mode = alc880_w810_modes,
4345 .input_mux = &alc880_capture_source,
4346 },
4347 [ALC880_Z71V] = {
e9edcee0 4348 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4349 .init_verbs = { alc880_volume_init_verbs,
4350 alc880_pin_z71v_init_verbs },
16ded525
TI
4351 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4352 .dac_nids = alc880_z71v_dac_nids,
4353 .dig_out_nid = ALC880_DIGOUT_NID,
4354 .hp_nid = 0x03,
e9edcee0
TI
4355 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4356 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4357 .input_mux = &alc880_capture_source,
4358 },
4359 [ALC880_F1734] = {
e9edcee0 4360 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4361 .init_verbs = { alc880_volume_init_verbs,
4362 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4363 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4364 .dac_nids = alc880_f1734_dac_nids,
4365 .hp_nid = 0x02,
4366 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4367 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4368 .input_mux = &alc880_f1734_capture_source,
4369 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4370 .setup = alc880_uniwill_p53_setup,
4371 .init_hook = alc_automute_amp,
16ded525
TI
4372 },
4373 [ALC880_ASUS] = {
e9edcee0 4374 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4375 .init_verbs = { alc880_volume_init_verbs,
4376 alc880_pin_asus_init_verbs,
e9edcee0
TI
4377 alc880_gpio1_init_verbs },
4378 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4379 .dac_nids = alc880_asus_dac_nids,
4380 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4381 .channel_mode = alc880_asus_modes,
4e195a7b 4382 .need_dac_fix = 1,
16ded525
TI
4383 .input_mux = &alc880_capture_source,
4384 },
4385 [ALC880_ASUS_DIG] = {
e9edcee0 4386 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4387 .init_verbs = { alc880_volume_init_verbs,
4388 alc880_pin_asus_init_verbs,
e9edcee0
TI
4389 alc880_gpio1_init_verbs },
4390 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4391 .dac_nids = alc880_asus_dac_nids,
16ded525 4392 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4393 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4394 .channel_mode = alc880_asus_modes,
4e195a7b 4395 .need_dac_fix = 1,
16ded525
TI
4396 .input_mux = &alc880_capture_source,
4397 },
df694daa
KY
4398 [ALC880_ASUS_DIG2] = {
4399 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4400 .init_verbs = { alc880_volume_init_verbs,
4401 alc880_pin_asus_init_verbs,
df694daa
KY
4402 alc880_gpio2_init_verbs }, /* use GPIO2 */
4403 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4404 .dac_nids = alc880_asus_dac_nids,
4405 .dig_out_nid = ALC880_DIGOUT_NID,
4406 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4407 .channel_mode = alc880_asus_modes,
4e195a7b 4408 .need_dac_fix = 1,
df694daa
KY
4409 .input_mux = &alc880_capture_source,
4410 },
16ded525 4411 [ALC880_ASUS_W1V] = {
e9edcee0 4412 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4413 .init_verbs = { alc880_volume_init_verbs,
4414 alc880_pin_asus_init_verbs,
e9edcee0
TI
4415 alc880_gpio1_init_verbs },
4416 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4417 .dac_nids = alc880_asus_dac_nids,
16ded525 4418 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4419 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4420 .channel_mode = alc880_asus_modes,
4e195a7b 4421 .need_dac_fix = 1,
16ded525
TI
4422 .input_mux = &alc880_capture_source,
4423 },
4424 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4425 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4426 .init_verbs = { alc880_volume_init_verbs,
4427 alc880_pin_asus_init_verbs },
e9edcee0
TI
4428 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4429 .dac_nids = alc880_asus_dac_nids,
16ded525 4430 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4431 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4432 .channel_mode = alc880_asus_modes,
4e195a7b 4433 .need_dac_fix = 1,
16ded525
TI
4434 .input_mux = &alc880_capture_source,
4435 },
ccc656ce
KY
4436 [ALC880_UNIWILL] = {
4437 .mixers = { alc880_uniwill_mixer },
4438 .init_verbs = { alc880_volume_init_verbs,
4439 alc880_uniwill_init_verbs },
4440 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4441 .dac_nids = alc880_asus_dac_nids,
4442 .dig_out_nid = ALC880_DIGOUT_NID,
4443 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4444 .channel_mode = alc880_threestack_modes,
4445 .need_dac_fix = 1,
4446 .input_mux = &alc880_capture_source,
4447 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4448 .setup = alc880_uniwill_setup,
a9fd4f3f 4449 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4450 },
4451 [ALC880_UNIWILL_P53] = {
4452 .mixers = { alc880_uniwill_p53_mixer },
4453 .init_verbs = { alc880_volume_init_verbs,
4454 alc880_uniwill_p53_init_verbs },
4455 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4456 .dac_nids = alc880_asus_dac_nids,
4457 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4458 .channel_mode = alc880_threestack_modes,
4459 .input_mux = &alc880_capture_source,
4460 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4461 .setup = alc880_uniwill_p53_setup,
4462 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4463 },
4464 [ALC880_FUJITSU] = {
45bdd1c1 4465 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4466 .init_verbs = { alc880_volume_init_verbs,
4467 alc880_uniwill_p53_init_verbs,
4468 alc880_beep_init_verbs },
4469 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4470 .dac_nids = alc880_dac_nids,
d53d7d9e 4471 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4472 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4473 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4474 .input_mux = &alc880_capture_source,
4475 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4476 .setup = alc880_uniwill_p53_setup,
4477 .init_hook = alc_automute_amp,
ccc656ce 4478 },
df694daa
KY
4479 [ALC880_CLEVO] = {
4480 .mixers = { alc880_three_stack_mixer },
4481 .init_verbs = { alc880_volume_init_verbs,
4482 alc880_pin_clevo_init_verbs },
4483 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4484 .dac_nids = alc880_dac_nids,
4485 .hp_nid = 0x03,
4486 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4487 .channel_mode = alc880_threestack_modes,
4e195a7b 4488 .need_dac_fix = 1,
df694daa
KY
4489 .input_mux = &alc880_capture_source,
4490 },
ae6b813a
TI
4491 [ALC880_LG] = {
4492 .mixers = { alc880_lg_mixer },
4493 .init_verbs = { alc880_volume_init_verbs,
4494 alc880_lg_init_verbs },
4495 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4496 .dac_nids = alc880_lg_dac_nids,
4497 .dig_out_nid = ALC880_DIGOUT_NID,
4498 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4499 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4500 .need_dac_fix = 1,
ae6b813a 4501 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4502 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4503 .setup = alc880_lg_setup,
4504 .init_hook = alc_automute_amp,
cb53c626
TI
4505#ifdef CONFIG_SND_HDA_POWER_SAVE
4506 .loopbacks = alc880_lg_loopbacks,
4507#endif
ae6b813a 4508 },
d681518a
TI
4509 [ALC880_LG_LW] = {
4510 .mixers = { alc880_lg_lw_mixer },
4511 .init_verbs = { alc880_volume_init_verbs,
4512 alc880_lg_lw_init_verbs },
0a8c5da3 4513 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4514 .dac_nids = alc880_dac_nids,
4515 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4516 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4517 .channel_mode = alc880_lg_lw_modes,
d681518a 4518 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4519 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4520 .setup = alc880_lg_lw_setup,
4521 .init_hook = alc_automute_amp,
d681518a 4522 },
df99cd33
TI
4523 [ALC880_MEDION_RIM] = {
4524 .mixers = { alc880_medion_rim_mixer },
4525 .init_verbs = { alc880_volume_init_verbs,
4526 alc880_medion_rim_init_verbs,
4527 alc_gpio2_init_verbs },
4528 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4529 .dac_nids = alc880_dac_nids,
4530 .dig_out_nid = ALC880_DIGOUT_NID,
4531 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4532 .channel_mode = alc880_2_jack_modes,
4533 .input_mux = &alc880_medion_rim_capture_source,
4534 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4535 .setup = alc880_medion_rim_setup,
4536 .init_hook = alc880_medion_rim_automute,
df99cd33 4537 },
16ded525
TI
4538#ifdef CONFIG_SND_DEBUG
4539 [ALC880_TEST] = {
e9edcee0
TI
4540 .mixers = { alc880_test_mixer },
4541 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4542 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4543 .dac_nids = alc880_test_dac_nids,
4544 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4545 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4546 .channel_mode = alc880_test_modes,
4547 .input_mux = &alc880_test_capture_source,
4548 },
4549#endif
4550};
4551
e9edcee0
TI
4552/*
4553 * Automatic parse of I/O pins from the BIOS configuration
4554 */
4555
e9edcee0
TI
4556enum {
4557 ALC_CTL_WIDGET_VOL,
4558 ALC_CTL_WIDGET_MUTE,
4559 ALC_CTL_BIND_MUTE,
4560};
c8b6bf9b 4561static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4562 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4563 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4564 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4565};
4566
4567/* add dynamic controls */
f12ab1e0
TI
4568static int add_control(struct alc_spec *spec, int type, const char *name,
4569 unsigned long val)
e9edcee0 4570{
c8b6bf9b 4571 struct snd_kcontrol_new *knew;
e9edcee0 4572
603c4019
TI
4573 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4574 knew = snd_array_new(&spec->kctls);
4575 if (!knew)
4576 return -ENOMEM;
e9edcee0 4577 *knew = alc880_control_templates[type];
543537bd 4578 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4579 if (!knew->name)
e9edcee0 4580 return -ENOMEM;
4d02d1b6 4581 if (get_amp_nid_(val))
5e26dfd0 4582 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4583 knew->private_value = val;
e9edcee0
TI
4584 return 0;
4585}
4586
0afe5f89
TI
4587static int add_control_with_pfx(struct alc_spec *spec, int type,
4588 const char *pfx, const char *dir,
4589 const char *sfx, unsigned long val)
4590{
4591 char name[32];
4592 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4593 return add_control(spec, type, name, val);
4594}
4595
4596#define add_pb_vol_ctrl(spec, type, pfx, val) \
4597 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4598#define add_pb_sw_ctrl(spec, type, pfx, val) \
4599 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4600
e9edcee0
TI
4601#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4602#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4603#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4604#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4605#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4606#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4607#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4608#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4609#define ALC880_PIN_CD_NID 0x1c
4610
4611/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4612static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4613 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4614{
4615 hda_nid_t nid;
4616 int assigned[4];
4617 int i, j;
4618
4619 memset(assigned, 0, sizeof(assigned));
b0af0de5 4620 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4621
4622 /* check the pins hardwired to audio widget */
4623 for (i = 0; i < cfg->line_outs; i++) {
4624 nid = cfg->line_out_pins[i];
4625 if (alc880_is_fixed_pin(nid)) {
4626 int idx = alc880_fixed_pin_idx(nid);
5014f193 4627 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4628 assigned[idx] = 1;
4629 }
4630 }
4631 /* left pins can be connect to any audio widget */
4632 for (i = 0; i < cfg->line_outs; i++) {
4633 nid = cfg->line_out_pins[i];
4634 if (alc880_is_fixed_pin(nid))
4635 continue;
4636 /* search for an empty channel */
4637 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4638 if (!assigned[j]) {
4639 spec->multiout.dac_nids[i] =
4640 alc880_idx_to_dac(j);
e9edcee0
TI
4641 assigned[j] = 1;
4642 break;
4643 }
4644 }
4645 }
4646 spec->multiout.num_dacs = cfg->line_outs;
4647 return 0;
4648}
4649
4650/* add playback controls from the parsed DAC table */
df694daa
KY
4651static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4652 const struct auto_pin_cfg *cfg)
e9edcee0 4653{
f12ab1e0
TI
4654 static const char *chname[4] = {
4655 "Front", "Surround", NULL /*CLFE*/, "Side"
4656 };
e9edcee0
TI
4657 hda_nid_t nid;
4658 int i, err;
4659
4660 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4661 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4662 continue;
4663 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4664 if (i == 2) {
4665 /* Center/LFE */
0afe5f89
TI
4666 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4667 "Center",
f12ab1e0
TI
4668 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4669 HDA_OUTPUT));
4670 if (err < 0)
e9edcee0 4671 return err;
0afe5f89
TI
4672 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4673 "LFE",
f12ab1e0
TI
4674 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4675 HDA_OUTPUT));
4676 if (err < 0)
e9edcee0 4677 return err;
0afe5f89
TI
4678 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4679 "Center",
f12ab1e0
TI
4680 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4681 HDA_INPUT));
4682 if (err < 0)
e9edcee0 4683 return err;
0afe5f89
TI
4684 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4685 "LFE",
f12ab1e0
TI
4686 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4687 HDA_INPUT));
4688 if (err < 0)
e9edcee0
TI
4689 return err;
4690 } else {
cb162b6b
TI
4691 const char *pfx;
4692 if (cfg->line_outs == 1 &&
4693 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4694 pfx = "Speaker";
4695 else
4696 pfx = chname[i];
0afe5f89 4697 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4698 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4699 HDA_OUTPUT));
4700 if (err < 0)
e9edcee0 4701 return err;
0afe5f89 4702 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4703 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4704 HDA_INPUT));
4705 if (err < 0)
e9edcee0
TI
4706 return err;
4707 }
4708 }
e9edcee0
TI
4709 return 0;
4710}
4711
8d88bc3d
TI
4712/* add playback controls for speaker and HP outputs */
4713static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4714 const char *pfx)
e9edcee0
TI
4715{
4716 hda_nid_t nid;
4717 int err;
4718
f12ab1e0 4719 if (!pin)
e9edcee0
TI
4720 return 0;
4721
4722 if (alc880_is_fixed_pin(pin)) {
4723 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4724 /* specify the DAC as the extra output */
f12ab1e0 4725 if (!spec->multiout.hp_nid)
e9edcee0 4726 spec->multiout.hp_nid = nid;
82bc955f
TI
4727 else
4728 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4729 /* control HP volume/switch on the output mixer amp */
4730 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4731 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4732 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4733 if (err < 0)
e9edcee0 4734 return err;
0afe5f89 4735 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4736 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4737 if (err < 0)
e9edcee0
TI
4738 return err;
4739 } else if (alc880_is_multi_pin(pin)) {
4740 /* set manual connection */
e9edcee0 4741 /* we have only a switch on HP-out PIN */
0afe5f89 4742 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4743 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4744 if (err < 0)
e9edcee0
TI
4745 return err;
4746 }
4747 return 0;
4748}
4749
4750/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4751static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4752 const char *ctlname,
df694daa 4753 int idx, hda_nid_t mix_nid)
e9edcee0 4754{
df694daa 4755 int err;
e9edcee0 4756
0afe5f89 4757 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4758 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4759 if (err < 0)
e9edcee0 4760 return err;
0afe5f89 4761 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4762 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4763 if (err < 0)
e9edcee0
TI
4764 return err;
4765 return 0;
4766}
4767
05f5f477
TI
4768static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4769{
4770 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4771 return (pincap & AC_PINCAP_IN) != 0;
4772}
4773
e9edcee0 4774/* create playback/capture controls for input pins */
05f5f477
TI
4775static int alc_auto_create_input_ctls(struct hda_codec *codec,
4776 const struct auto_pin_cfg *cfg,
4777 hda_nid_t mixer,
4778 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4779{
05f5f477 4780 struct alc_spec *spec = codec->spec;
61b9b9b1 4781 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4782 int i, err, idx;
e9edcee0
TI
4783
4784 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4785 hda_nid_t pin;
4786
4787 pin = cfg->input_pins[i];
4788 if (!alc_is_input_pin(codec, pin))
4789 continue;
4790
4791 if (mixer) {
4792 idx = get_connection_index(codec, mixer, pin);
4793 if (idx >= 0) {
4794 err = new_analog_input(spec, pin,
4795 auto_pin_cfg_labels[i],
4796 idx, mixer);
4797 if (err < 0)
4798 return err;
4799 }
4800 }
4801
4802 if (!cap1)
4803 continue;
4804 idx = get_connection_index(codec, cap1, pin);
4805 if (idx < 0 && cap2)
4806 idx = get_connection_index(codec, cap2, pin);
4807 if (idx >= 0) {
f12ab1e0
TI
4808 imux->items[imux->num_items].label =
4809 auto_pin_cfg_labels[i];
05f5f477 4810 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4811 imux->num_items++;
4812 }
4813 }
4814 return 0;
4815}
4816
05f5f477
TI
4817static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4818 const struct auto_pin_cfg *cfg)
4819{
4820 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4821}
4822
f6c7e546
TI
4823static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4824 unsigned int pin_type)
4825{
4826 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4827 pin_type);
4828 /* unmute pin */
d260cdf6
TI
4829 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4830 AMP_OUT_UNMUTE);
f6c7e546
TI
4831}
4832
df694daa
KY
4833static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4834 hda_nid_t nid, int pin_type,
e9edcee0
TI
4835 int dac_idx)
4836{
f6c7e546 4837 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4838 /* need the manual connection? */
4839 if (alc880_is_multi_pin(nid)) {
4840 struct alc_spec *spec = codec->spec;
4841 int idx = alc880_multi_pin_idx(nid);
4842 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4843 AC_VERB_SET_CONNECT_SEL,
4844 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4845 }
4846}
4847
baba8ee9
TI
4848static int get_pin_type(int line_out_type)
4849{
4850 if (line_out_type == AUTO_PIN_HP_OUT)
4851 return PIN_HP;
4852 else
4853 return PIN_OUT;
4854}
4855
e9edcee0
TI
4856static void alc880_auto_init_multi_out(struct hda_codec *codec)
4857{
4858 struct alc_spec *spec = codec->spec;
4859 int i;
ea1fb29a 4860
e9edcee0
TI
4861 for (i = 0; i < spec->autocfg.line_outs; i++) {
4862 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4863 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4864 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4865 }
4866}
4867
8d88bc3d 4868static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4869{
4870 struct alc_spec *spec = codec->spec;
4871 hda_nid_t pin;
4872
82bc955f 4873 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4874 if (pin) /* connect to front */
4875 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4876 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4877 if (pin) /* connect to front */
4878 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4879}
4880
4881static void alc880_auto_init_analog_input(struct hda_codec *codec)
4882{
4883 struct alc_spec *spec = codec->spec;
4884 int i;
4885
4886 for (i = 0; i < AUTO_PIN_LAST; i++) {
4887 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 4888 if (alc_is_input_pin(codec, nid)) {
23f0c048 4889 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4890 if (nid != ALC880_PIN_CD_NID &&
4891 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4892 snd_hda_codec_write(codec, nid, 0,
4893 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4894 AMP_OUT_MUTE);
4895 }
4896 }
4897}
4898
4899/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4900/* return 1 if successful, 0 if the proper config is not found,
4901 * or a negative error code
4902 */
e9edcee0
TI
4903static int alc880_parse_auto_config(struct hda_codec *codec)
4904{
4905 struct alc_spec *spec = codec->spec;
6a05ac4a 4906 int i, err;
df694daa 4907 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4908
f12ab1e0
TI
4909 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4910 alc880_ignore);
4911 if (err < 0)
e9edcee0 4912 return err;
f12ab1e0 4913 if (!spec->autocfg.line_outs)
e9edcee0 4914 return 0; /* can't find valid BIOS pin config */
df694daa 4915
f12ab1e0
TI
4916 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4917 if (err < 0)
4918 return err;
4919 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4920 if (err < 0)
4921 return err;
4922 err = alc880_auto_create_extra_out(spec,
4923 spec->autocfg.speaker_pins[0],
4924 "Speaker");
4925 if (err < 0)
4926 return err;
4927 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4928 "Headphone");
4929 if (err < 0)
4930 return err;
05f5f477 4931 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 4932 if (err < 0)
e9edcee0
TI
4933 return err;
4934
4935 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4936
6a05ac4a
TI
4937 /* check multiple SPDIF-out (for recent codecs) */
4938 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4939 hda_nid_t dig_nid;
4940 err = snd_hda_get_connections(codec,
4941 spec->autocfg.dig_out_pins[i],
4942 &dig_nid, 1);
4943 if (err < 0)
4944 continue;
4945 if (!i)
4946 spec->multiout.dig_out_nid = dig_nid;
4947 else {
4948 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 4949 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
6a05ac4a 4950 break;
71121d9f 4951 spec->slave_dig_outs[i - 1] = dig_nid;
6a05ac4a
TI
4952 }
4953 }
e9edcee0
TI
4954 if (spec->autocfg.dig_in_pin)
4955 spec->dig_in_nid = ALC880_DIGIN_NID;
4956
603c4019 4957 if (spec->kctls.list)
d88897ea 4958 add_mixer(spec, spec->kctls.list);
e9edcee0 4959
d88897ea 4960 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4961
a1e8d2da 4962 spec->num_mux_defs = 1;
61b9b9b1 4963 spec->input_mux = &spec->private_imux[0];
e9edcee0 4964
6227cdce 4965 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 4966
e9edcee0
TI
4967 return 1;
4968}
4969
ae6b813a
TI
4970/* additional initialization for auto-configuration model */
4971static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4972{
f6c7e546 4973 struct alc_spec *spec = codec->spec;
e9edcee0 4974 alc880_auto_init_multi_out(codec);
8d88bc3d 4975 alc880_auto_init_extra_out(codec);
e9edcee0 4976 alc880_auto_init_analog_input(codec);
f6c7e546 4977 if (spec->unsol_event)
7fb0d78f 4978 alc_inithook(codec);
e9edcee0
TI
4979}
4980
b59bdf3b
TI
4981/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4982 * one of two digital mic pins, e.g. on ALC272
4983 */
4984static void fixup_automic_adc(struct hda_codec *codec)
4985{
4986 struct alc_spec *spec = codec->spec;
4987 int i;
4988
4989 for (i = 0; i < spec->num_adc_nids; i++) {
4990 hda_nid_t cap = spec->capsrc_nids ?
4991 spec->capsrc_nids[i] : spec->adc_nids[i];
4992 int iidx, eidx;
4993
4994 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4995 if (iidx < 0)
4996 continue;
4997 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4998 if (eidx < 0)
4999 continue;
5000 spec->int_mic.mux_idx = iidx;
5001 spec->ext_mic.mux_idx = eidx;
5002 if (spec->capsrc_nids)
5003 spec->capsrc_nids += i;
5004 spec->adc_nids += i;
5005 spec->num_adc_nids = 1;
5006 return;
5007 }
5008 snd_printd(KERN_INFO "hda_codec: %s: "
5009 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5010 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5011 spec->auto_mic = 0; /* disable auto-mic to be sure */
5012}
5013
eaa9b3a7
TI
5014/* choose the ADC/MUX containing the input pin and initialize the setup */
5015static void fixup_single_adc(struct hda_codec *codec)
5016{
5017 struct alc_spec *spec = codec->spec;
d2db09b8 5018 hda_nid_t pin = 0;
eaa9b3a7
TI
5019 int i;
5020
5021 /* search for the input pin; there must be only one */
5022 for (i = 0; i < AUTO_PIN_LAST; i++) {
5023 if (spec->autocfg.input_pins[i]) {
5024 pin = spec->autocfg.input_pins[i];
5025 break;
5026 }
5027 }
5028 if (!pin)
5029 return;
5030
5031 /* set the default connection to that pin */
5032 for (i = 0; i < spec->num_adc_nids; i++) {
5033 hda_nid_t cap = spec->capsrc_nids ?
5034 spec->capsrc_nids[i] : spec->adc_nids[i];
5035 int idx;
5036
5037 idx = get_connection_index(codec, cap, pin);
5038 if (idx < 0)
5039 continue;
5040 /* use only this ADC */
5041 if (spec->capsrc_nids)
5042 spec->capsrc_nids += i;
5043 spec->adc_nids += i;
5044 spec->num_adc_nids = 1;
5045 /* select or unmute this route */
5046 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5047 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5048 HDA_AMP_MUTE, 0);
5049 } else {
5050 snd_hda_codec_write_cache(codec, cap, 0,
5051 AC_VERB_SET_CONNECT_SEL, idx);
5052 }
5053 return;
5054 }
5055}
5056
b59bdf3b 5057static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5058{
b59bdf3b 5059 struct alc_spec *spec = codec->spec;
a23b688f
TI
5060 static struct snd_kcontrol_new *caps[2][3] = {
5061 { alc_capture_mixer_nosrc1,
5062 alc_capture_mixer_nosrc2,
5063 alc_capture_mixer_nosrc3 },
5064 { alc_capture_mixer1,
5065 alc_capture_mixer2,
5066 alc_capture_mixer3 },
f9e336f6 5067 };
a23b688f 5068 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7
TI
5069 int mux = 0;
5070 if (spec->auto_mic)
b59bdf3b 5071 fixup_automic_adc(codec);
eaa9b3a7
TI
5072 else if (spec->input_mux) {
5073 if (spec->input_mux->num_items > 1)
5074 mux = 1;
5075 else if (spec->input_mux->num_items == 1)
5076 fixup_single_adc(codec);
5077 }
a23b688f
TI
5078 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
5079 }
f9e336f6
TI
5080}
5081
6694635d
TI
5082/* fill adc_nids (and capsrc_nids) containing all active input pins */
5083static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5084 int num_nids)
5085{
5086 struct alc_spec *spec = codec->spec;
5087 int n;
5088 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5089
5090 for (n = 0; n < num_nids; n++) {
5091 hda_nid_t adc, cap;
5092 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5093 int nconns, i, j;
5094
5095 adc = nids[n];
5096 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5097 continue;
5098 cap = adc;
5099 nconns = snd_hda_get_connections(codec, cap, conn,
5100 ARRAY_SIZE(conn));
5101 if (nconns == 1) {
5102 cap = conn[0];
5103 nconns = snd_hda_get_connections(codec, cap, conn,
5104 ARRAY_SIZE(conn));
5105 }
5106 if (nconns <= 0)
5107 continue;
5108 if (!fallback_adc) {
5109 fallback_adc = adc;
5110 fallback_cap = cap;
5111 }
5112 for (i = 0; i < AUTO_PIN_LAST; i++) {
5113 hda_nid_t nid = spec->autocfg.input_pins[i];
5114 if (!nid)
5115 continue;
5116 for (j = 0; j < nconns; j++) {
5117 if (conn[j] == nid)
5118 break;
5119 }
5120 if (j >= nconns)
5121 break;
5122 }
5123 if (i >= AUTO_PIN_LAST) {
5124 int num_adcs = spec->num_adc_nids;
5125 spec->private_adc_nids[num_adcs] = adc;
5126 spec->private_capsrc_nids[num_adcs] = cap;
5127 spec->num_adc_nids++;
5128 spec->adc_nids = spec->private_adc_nids;
5129 if (adc != cap)
5130 spec->capsrc_nids = spec->private_capsrc_nids;
5131 }
5132 }
5133 if (!spec->num_adc_nids) {
5134 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5135 " using fallback 0x%x\n",
5136 codec->chip_name, fallback_adc);
6694635d
TI
5137 spec->private_adc_nids[0] = fallback_adc;
5138 spec->adc_nids = spec->private_adc_nids;
5139 if (fallback_adc != fallback_cap) {
5140 spec->private_capsrc_nids[0] = fallback_cap;
5141 spec->capsrc_nids = spec->private_adc_nids;
5142 }
5143 }
5144}
5145
67d634c0 5146#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5147#define set_beep_amp(spec, nid, idx, dir) \
5148 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
67d634c0
TI
5149#else
5150#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5151#endif
45bdd1c1
TI
5152
5153/*
5154 * OK, here we have finally the patch for ALC880
5155 */
5156
1da177e4
LT
5157static int patch_alc880(struct hda_codec *codec)
5158{
5159 struct alc_spec *spec;
5160 int board_config;
df694daa 5161 int err;
1da177e4 5162
e560d8d8 5163 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5164 if (spec == NULL)
5165 return -ENOMEM;
5166
5167 codec->spec = spec;
5168
f5fcc13c
TI
5169 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5170 alc880_models,
5171 alc880_cfg_tbl);
5172 if (board_config < 0) {
9a11f1aa
TI
5173 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5174 codec->chip_name);
e9edcee0 5175 board_config = ALC880_AUTO;
1da177e4 5176 }
1da177e4 5177
e9edcee0
TI
5178 if (board_config == ALC880_AUTO) {
5179 /* automatic parse from the BIOS config */
5180 err = alc880_parse_auto_config(codec);
5181 if (err < 0) {
5182 alc_free(codec);
5183 return err;
f12ab1e0 5184 } else if (!err) {
9c7f852e
TI
5185 printk(KERN_INFO
5186 "hda_codec: Cannot set up configuration "
5187 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5188 board_config = ALC880_3ST;
5189 }
1da177e4
LT
5190 }
5191
680cd536
KK
5192 err = snd_hda_attach_beep_device(codec, 0x1);
5193 if (err < 0) {
5194 alc_free(codec);
5195 return err;
5196 }
5197
df694daa 5198 if (board_config != ALC880_AUTO)
e9c364c0 5199 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5200
1da177e4
LT
5201 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5202 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5203 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5204
1da177e4
LT
5205 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5206 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5207
f12ab1e0 5208 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5209 /* check whether NID 0x07 is valid */
54d17403 5210 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5211 /* get type */
a22d543a 5212 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5213 if (wcap != AC_WID_AUD_IN) {
5214 spec->adc_nids = alc880_adc_nids_alt;
5215 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5216 } else {
5217 spec->adc_nids = alc880_adc_nids;
5218 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5219 }
5220 }
b59bdf3b 5221 set_capture_mixer(codec);
45bdd1c1 5222 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5223
2134ea4f
TI
5224 spec->vmaster_nid = 0x0c;
5225
1da177e4 5226 codec->patch_ops = alc_patch_ops;
e9edcee0 5227 if (board_config == ALC880_AUTO)
ae6b813a 5228 spec->init_hook = alc880_auto_init;
cb53c626
TI
5229#ifdef CONFIG_SND_HDA_POWER_SAVE
5230 if (!spec->loopback.amplist)
5231 spec->loopback.amplist = alc880_loopbacks;
5232#endif
1da177e4
LT
5233
5234 return 0;
5235}
5236
e9edcee0 5237
1da177e4
LT
5238/*
5239 * ALC260 support
5240 */
5241
e9edcee0
TI
5242static hda_nid_t alc260_dac_nids[1] = {
5243 /* front */
5244 0x02,
5245};
5246
5247static hda_nid_t alc260_adc_nids[1] = {
5248 /* ADC0 */
5249 0x04,
5250};
5251
df694daa 5252static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5253 /* ADC1 */
5254 0x05,
5255};
5256
d57fdac0
JW
5257/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5258 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5259 */
5260static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5261 /* ADC0, ADC1 */
5262 0x04, 0x05
5263};
5264
e9edcee0
TI
5265#define ALC260_DIGOUT_NID 0x03
5266#define ALC260_DIGIN_NID 0x06
5267
5268static struct hda_input_mux alc260_capture_source = {
5269 .num_items = 4,
5270 .items = {
5271 { "Mic", 0x0 },
5272 { "Front Mic", 0x1 },
5273 { "Line", 0x2 },
5274 { "CD", 0x4 },
5275 },
5276};
5277
17e7aec6 5278/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5279 * headphone jack and the internal CD lines since these are the only pins at
5280 * which audio can appear. For flexibility, also allow the option of
5281 * recording the mixer output on the second ADC (ADC0 doesn't have a
5282 * connection to the mixer output).
a9430dd8 5283 */
a1e8d2da
JW
5284static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5285 {
5286 .num_items = 3,
5287 .items = {
5288 { "Mic/Line", 0x0 },
5289 { "CD", 0x4 },
5290 { "Headphone", 0x2 },
5291 },
a9430dd8 5292 },
a1e8d2da
JW
5293 {
5294 .num_items = 4,
5295 .items = {
5296 { "Mic/Line", 0x0 },
5297 { "CD", 0x4 },
5298 { "Headphone", 0x2 },
5299 { "Mixer", 0x5 },
5300 },
5301 },
5302
a9430dd8
JW
5303};
5304
a1e8d2da
JW
5305/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5306 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5307 */
a1e8d2da
JW
5308static struct hda_input_mux alc260_acer_capture_sources[2] = {
5309 {
5310 .num_items = 4,
5311 .items = {
5312 { "Mic", 0x0 },
5313 { "Line", 0x2 },
5314 { "CD", 0x4 },
5315 { "Headphone", 0x5 },
5316 },
5317 },
5318 {
5319 .num_items = 5,
5320 .items = {
5321 { "Mic", 0x0 },
5322 { "Line", 0x2 },
5323 { "CD", 0x4 },
5324 { "Headphone", 0x6 },
5325 { "Mixer", 0x5 },
5326 },
0bfc90e9
JW
5327 },
5328};
cc959489
MS
5329
5330/* Maxdata Favorit 100XS */
5331static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5332 {
5333 .num_items = 2,
5334 .items = {
5335 { "Line/Mic", 0x0 },
5336 { "CD", 0x4 },
5337 },
5338 },
5339 {
5340 .num_items = 3,
5341 .items = {
5342 { "Line/Mic", 0x0 },
5343 { "CD", 0x4 },
5344 { "Mixer", 0x5 },
5345 },
5346 },
5347};
5348
1da177e4
LT
5349/*
5350 * This is just place-holder, so there's something for alc_build_pcms to look
5351 * at when it calculates the maximum number of channels. ALC260 has no mixer
5352 * element which allows changing the channel mode, so the verb list is
5353 * never used.
5354 */
d2a6d7dc 5355static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5356 { 2, NULL },
5357};
5358
df694daa
KY
5359
5360/* Mixer combinations
5361 *
5362 * basic: base_output + input + pc_beep + capture
5363 * HP: base_output + input + capture_alt
5364 * HP_3013: hp_3013 + input + capture
5365 * fujitsu: fujitsu + capture
0bfc90e9 5366 * acer: acer + capture
df694daa
KY
5367 */
5368
5369static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5370 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5371 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5372 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5373 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5374 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5375 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5376 { } /* end */
f12ab1e0 5377};
1da177e4 5378
df694daa 5379static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5380 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5381 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5382 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5383 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5384 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5385 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5386 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5388 { } /* end */
5389};
5390
bec15c3a
TI
5391/* update HP, line and mono out pins according to the master switch */
5392static void alc260_hp_master_update(struct hda_codec *codec,
5393 hda_nid_t hp, hda_nid_t line,
5394 hda_nid_t mono)
5395{
5396 struct alc_spec *spec = codec->spec;
5397 unsigned int val = spec->master_sw ? PIN_HP : 0;
5398 /* change HP and line-out pins */
30cde0aa 5399 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5400 val);
30cde0aa 5401 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5402 val);
5403 /* mono (speaker) depending on the HP jack sense */
5404 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5405 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5406 val);
5407}
5408
5409static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5410 struct snd_ctl_elem_value *ucontrol)
5411{
5412 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5413 struct alc_spec *spec = codec->spec;
5414 *ucontrol->value.integer.value = spec->master_sw;
5415 return 0;
5416}
5417
5418static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5419 struct snd_ctl_elem_value *ucontrol)
5420{
5421 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5422 struct alc_spec *spec = codec->spec;
5423 int val = !!*ucontrol->value.integer.value;
5424 hda_nid_t hp, line, mono;
5425
5426 if (val == spec->master_sw)
5427 return 0;
5428 spec->master_sw = val;
5429 hp = (kcontrol->private_value >> 16) & 0xff;
5430 line = (kcontrol->private_value >> 8) & 0xff;
5431 mono = kcontrol->private_value & 0xff;
5432 alc260_hp_master_update(codec, hp, line, mono);
5433 return 1;
5434}
5435
5436static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5437 {
5438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5439 .name = "Master Playback Switch",
5b0cb1d8 5440 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5441 .info = snd_ctl_boolean_mono_info,
5442 .get = alc260_hp_master_sw_get,
5443 .put = alc260_hp_master_sw_put,
5444 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5445 },
5446 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5447 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5448 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5449 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5450 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5451 HDA_OUTPUT),
5452 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5453 { } /* end */
5454};
5455
5456static struct hda_verb alc260_hp_unsol_verbs[] = {
5457 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5458 {},
5459};
5460
5461static void alc260_hp_automute(struct hda_codec *codec)
5462{
5463 struct alc_spec *spec = codec->spec;
bec15c3a 5464
864f92be 5465 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5466 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5467}
5468
5469static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5470{
5471 if ((res >> 26) == ALC880_HP_EVENT)
5472 alc260_hp_automute(codec);
5473}
5474
df694daa 5475static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5476 {
5477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5478 .name = "Master Playback Switch",
5b0cb1d8 5479 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5480 .info = snd_ctl_boolean_mono_info,
5481 .get = alc260_hp_master_sw_get,
5482 .put = alc260_hp_master_sw_put,
30cde0aa 5483 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5484 },
df694daa
KY
5485 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5486 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5487 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5488 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5489 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5490 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5491 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5492 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5493 { } /* end */
5494};
5495
3f878308
KY
5496static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5497 .ops = &snd_hda_bind_vol,
5498 .values = {
5499 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5500 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5501 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5502 0
5503 },
5504};
5505
5506static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5507 .ops = &snd_hda_bind_sw,
5508 .values = {
5509 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5510 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5511 0
5512 },
5513};
5514
5515static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5516 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5517 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5518 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5520 { } /* end */
5521};
5522
bec15c3a
TI
5523static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5524 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5525 {},
5526};
5527
5528static void alc260_hp_3013_automute(struct hda_codec *codec)
5529{
5530 struct alc_spec *spec = codec->spec;
bec15c3a 5531
864f92be 5532 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5533 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5534}
5535
5536static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5537 unsigned int res)
5538{
5539 if ((res >> 26) == ALC880_HP_EVENT)
5540 alc260_hp_3013_automute(codec);
5541}
5542
3f878308
KY
5543static void alc260_hp_3012_automute(struct hda_codec *codec)
5544{
864f92be 5545 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5546
3f878308
KY
5547 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5548 bits);
5549 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5550 bits);
5551 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5552 bits);
5553}
5554
5555static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5556 unsigned int res)
5557{
5558 if ((res >> 26) == ALC880_HP_EVENT)
5559 alc260_hp_3012_automute(codec);
5560}
5561
5562/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5563 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5564 */
c8b6bf9b 5565static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5567 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5568 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5569 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5570 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5571 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5572 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5573 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5574 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5575 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5576 { } /* end */
5577};
5578
a1e8d2da
JW
5579/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5580 * versions of the ALC260 don't act on requests to enable mic bias from NID
5581 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5582 * datasheet doesn't mention this restriction. At this stage it's not clear
5583 * whether this behaviour is intentional or is a hardware bug in chip
5584 * revisions available in early 2006. Therefore for now allow the
5585 * "Headphone Jack Mode" control to span all choices, but if it turns out
5586 * that the lack of mic bias for this NID is intentional we could change the
5587 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5588 *
5589 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5590 * don't appear to make the mic bias available from the "line" jack, even
5591 * though the NID used for this jack (0x14) can supply it. The theory is
5592 * that perhaps Acer have included blocking capacitors between the ALC260
5593 * and the output jack. If this turns out to be the case for all such
5594 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5595 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5596 *
5597 * The C20x Tablet series have a mono internal speaker which is controlled
5598 * via the chip's Mono sum widget and pin complex, so include the necessary
5599 * controls for such models. On models without a "mono speaker" the control
5600 * won't do anything.
a1e8d2da 5601 */
0bfc90e9
JW
5602static struct snd_kcontrol_new alc260_acer_mixer[] = {
5603 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5604 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5605 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5606 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5607 HDA_OUTPUT),
31bffaa9 5608 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5609 HDA_INPUT),
0bfc90e9
JW
5610 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5611 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5612 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5613 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5614 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5615 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5616 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5617 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5618 { } /* end */
5619};
5620
cc959489
MS
5621/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5622 */
5623static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5624 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5625 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5626 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5627 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5628 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5629 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5630 { } /* end */
5631};
5632
bc9f98a9
KY
5633/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5634 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5635 */
5636static struct snd_kcontrol_new alc260_will_mixer[] = {
5637 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5638 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5640 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5641 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5642 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5643 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5644 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5645 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5646 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5647 { } /* end */
5648};
5649
5650/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5651 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5652 */
5653static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5654 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5655 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5657 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5658 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5659 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5660 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5661 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5662 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5663 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5664 { } /* end */
5665};
5666
df694daa
KY
5667/*
5668 * initialization verbs
5669 */
1da177e4
LT
5670static struct hda_verb alc260_init_verbs[] = {
5671 /* Line In pin widget for input */
05acb863 5672 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5673 /* CD pin widget for input */
05acb863 5674 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5675 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5676 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5677 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5678 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5679 /* LINE-2 is used for line-out in rear */
05acb863 5680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5681 /* select line-out */
fd56f2db 5682 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5683 /* LINE-OUT pin */
05acb863 5684 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5685 /* enable HP */
05acb863 5686 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5687 /* enable Mono */
05acb863
TI
5688 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5689 /* mute capture amp left and right */
16ded525 5690 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5691 /* set connection select to line in (default select for this ADC) */
5692 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5693 /* mute capture amp left and right */
5694 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5695 /* set connection select to line in (default select for this ADC) */
5696 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5697 /* set vol=0 Line-Out mixer amp left and right */
5698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5699 /* unmute pin widget amp left and right (no gain on this amp) */
5700 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5701 /* set vol=0 HP mixer amp left and right */
5702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5703 /* unmute pin widget amp left and right (no gain on this amp) */
5704 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5705 /* set vol=0 Mono mixer amp left and right */
5706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5707 /* unmute pin widget amp left and right (no gain on this amp) */
5708 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5709 /* unmute LINE-2 out pin */
5710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5711 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5712 * Line In 2 = 0x03
5713 */
cb53c626
TI
5714 /* mute analog inputs */
5715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5720 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5721 /* mute Front out path */
5722 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5723 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5724 /* mute Headphone out path */
5725 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5726 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5727 /* mute Mono out path */
5728 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5729 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5730 { }
5731};
5732
474167d6 5733#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5734static struct hda_verb alc260_hp_init_verbs[] = {
5735 /* Headphone and output */
5736 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5737 /* mono output */
5738 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5739 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5740 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5741 /* Mic2 (front panel) pin widget for input and vref at 80% */
5742 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5743 /* Line In pin widget for input */
5744 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5745 /* Line-2 pin widget for output */
5746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5747 /* CD pin widget for input */
5748 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5749 /* unmute amp left and right */
5750 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5751 /* set connection select to line in (default select for this ADC) */
5752 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5753 /* unmute Line-Out mixer amp left and right (volume = 0) */
5754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5755 /* mute pin widget amp left and right (no gain on this amp) */
5756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5757 /* unmute HP mixer amp left and right (volume = 0) */
5758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5759 /* mute pin widget amp left and right (no gain on this amp) */
5760 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5761 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5762 * Line In 2 = 0x03
5763 */
cb53c626
TI
5764 /* mute analog inputs */
5765 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5766 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5767 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5768 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5769 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5770 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5771 /* Unmute Front out path */
5772 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5773 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5774 /* Unmute Headphone out path */
5775 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5776 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5777 /* Unmute Mono out path */
5778 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5779 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5780 { }
5781};
474167d6 5782#endif
df694daa
KY
5783
5784static struct hda_verb alc260_hp_3013_init_verbs[] = {
5785 /* Line out and output */
5786 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5787 /* mono output */
5788 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5789 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5790 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5791 /* Mic2 (front panel) pin widget for input and vref at 80% */
5792 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5793 /* Line In pin widget for input */
5794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5795 /* Headphone pin widget for output */
5796 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5797 /* CD pin widget for input */
5798 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5799 /* unmute amp left and right */
5800 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5801 /* set connection select to line in (default select for this ADC) */
5802 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5803 /* unmute Line-Out mixer amp left and right (volume = 0) */
5804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5805 /* mute pin widget amp left and right (no gain on this amp) */
5806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5807 /* unmute HP mixer amp left and right (volume = 0) */
5808 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5809 /* mute pin widget amp left and right (no gain on this amp) */
5810 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5811 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5812 * Line In 2 = 0x03
5813 */
cb53c626
TI
5814 /* mute analog inputs */
5815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5820 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5821 /* Unmute Front out path */
5822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5824 /* Unmute Headphone out path */
5825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5827 /* Unmute Mono out path */
5828 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5830 { }
5831};
5832
a9430dd8 5833/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5834 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5835 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5836 */
5837static struct hda_verb alc260_fujitsu_init_verbs[] = {
5838 /* Disable all GPIOs */
5839 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5840 /* Internal speaker is connected to headphone pin */
5841 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5842 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5844 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5846 /* Ensure all other unused pins are disabled and muted. */
5847 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5849 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5850 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5851 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5852 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5855
5856 /* Disable digital (SPDIF) pins */
5857 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5858 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5859
ea1fb29a 5860 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5861 * when acting as an output.
5862 */
5863 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5864
f7ace40d 5865 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5866 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5867 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5869 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5870 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5873 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5874 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5875
f7ace40d
JW
5876 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5877 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5878 /* Unmute Line1 pin widget output buffer since it starts as an output.
5879 * If the pin mode is changed by the user the pin mode control will
5880 * take care of enabling the pin's input/output buffers as needed.
5881 * Therefore there's no need to enable the input buffer at this
5882 * stage.
cdcd9268 5883 */
f7ace40d 5884 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5885 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5886 * mixer ctrl)
5887 */
f7ace40d
JW
5888 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5889
5890 /* Mute capture amp left and right */
5891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5892 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5893 * in (on mic1 pin)
5894 */
5895 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5896
5897 /* Do the same for the second ADC: mute capture input amp and
5898 * set ADC connection to line in (on mic1 pin)
5899 */
5900 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5901 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5902
5903 /* Mute all inputs to mixer widget (even unconnected ones) */
5904 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5906 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5912
5913 { }
a9430dd8
JW
5914};
5915
0bfc90e9
JW
5916/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5917 * similar laptops (adapted from Fujitsu init verbs).
5918 */
5919static struct hda_verb alc260_acer_init_verbs[] = {
5920 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5921 * the headphone jack. Turn this on and rely on the standard mute
5922 * methods whenever the user wants to turn these outputs off.
5923 */
5924 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5925 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5926 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5927 /* Internal speaker/Headphone jack is connected to Line-out pin */
5928 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5929 /* Internal microphone/Mic jack is connected to Mic1 pin */
5930 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5931 /* Line In jack is connected to Line1 pin */
5932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5933 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5934 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5935 /* Ensure all other unused pins are disabled and muted. */
5936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5937 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5938 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5939 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5941 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5942 /* Disable digital (SPDIF) pins */
5943 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5944 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5945
ea1fb29a 5946 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5947 * bus when acting as outputs.
5948 */
5949 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5950 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5951
5952 /* Start with output sum widgets muted and their output gains at min */
5953 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5956 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5959 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5960 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5961 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5962
f12ab1e0
TI
5963 /* Unmute Line-out pin widget amp left and right
5964 * (no equiv mixer ctrl)
5965 */
0bfc90e9 5966 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5967 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5968 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5969 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5970 * inputs. If the pin mode is changed by the user the pin mode control
5971 * will take care of enabling the pin's input/output buffers as needed.
5972 * Therefore there's no need to enable the input buffer at this
5973 * stage.
5974 */
5975 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5976 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5977
5978 /* Mute capture amp left and right */
5979 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5980 /* Set ADC connection select to match default mixer setting - mic
5981 * (on mic1 pin)
5982 */
5983 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5984
5985 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5986 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5987 */
5988 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5989 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5990
5991 /* Mute all inputs to mixer widget (even unconnected ones) */
5992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6000
6001 { }
6002};
6003
cc959489
MS
6004/* Initialisation sequence for Maxdata Favorit 100XS
6005 * (adapted from Acer init verbs).
6006 */
6007static struct hda_verb alc260_favorit100_init_verbs[] = {
6008 /* GPIO 0 enables the output jack.
6009 * Turn this on and rely on the standard mute
6010 * methods whenever the user wants to turn these outputs off.
6011 */
6012 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6013 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6014 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6015 /* Line/Mic input jack is connected to Mic1 pin */
6016 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6017 /* Ensure all other unused pins are disabled and muted. */
6018 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6019 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6020 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6021 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6022 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6023 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6025 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6028 /* Disable digital (SPDIF) pins */
6029 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6030 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6031
6032 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6033 * bus when acting as outputs.
6034 */
6035 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6036 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6037
6038 /* Start with output sum widgets muted and their output gains at min */
6039 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6045 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6046 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6047 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6048
6049 /* Unmute Line-out pin widget amp left and right
6050 * (no equiv mixer ctrl)
6051 */
6052 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6053 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6054 * inputs. If the pin mode is changed by the user the pin mode control
6055 * will take care of enabling the pin's input/output buffers as needed.
6056 * Therefore there's no need to enable the input buffer at this
6057 * stage.
6058 */
6059 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6060
6061 /* Mute capture amp left and right */
6062 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6063 /* Set ADC connection select to match default mixer setting - mic
6064 * (on mic1 pin)
6065 */
6066 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6067
6068 /* Do similar with the second ADC: mute capture input amp and
6069 * set ADC connection to mic to match ALSA's default state.
6070 */
6071 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6072 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6073
6074 /* Mute all inputs to mixer widget (even unconnected ones) */
6075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6076 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6083
6084 { }
6085};
6086
bc9f98a9
KY
6087static struct hda_verb alc260_will_verbs[] = {
6088 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6089 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6090 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6091 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6092 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6093 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6094 {}
6095};
6096
6097static struct hda_verb alc260_replacer_672v_verbs[] = {
6098 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6099 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6100 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6101
6102 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6103 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6104 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6105
6106 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6107 {}
6108};
6109
6110/* toggle speaker-output according to the hp-jack state */
6111static void alc260_replacer_672v_automute(struct hda_codec *codec)
6112{
6113 unsigned int present;
6114
6115 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6116 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6117 if (present) {
82beb8fd
TI
6118 snd_hda_codec_write_cache(codec, 0x01, 0,
6119 AC_VERB_SET_GPIO_DATA, 1);
6120 snd_hda_codec_write_cache(codec, 0x0f, 0,
6121 AC_VERB_SET_PIN_WIDGET_CONTROL,
6122 PIN_HP);
bc9f98a9 6123 } else {
82beb8fd
TI
6124 snd_hda_codec_write_cache(codec, 0x01, 0,
6125 AC_VERB_SET_GPIO_DATA, 0);
6126 snd_hda_codec_write_cache(codec, 0x0f, 0,
6127 AC_VERB_SET_PIN_WIDGET_CONTROL,
6128 PIN_OUT);
bc9f98a9
KY
6129 }
6130}
6131
6132static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6133 unsigned int res)
6134{
6135 if ((res >> 26) == ALC880_HP_EVENT)
6136 alc260_replacer_672v_automute(codec);
6137}
6138
3f878308
KY
6139static struct hda_verb alc260_hp_dc7600_verbs[] = {
6140 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6141 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6142 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6143 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6144 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6146 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6147 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6148 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6150 {}
6151};
6152
7cf51e48
JW
6153/* Test configuration for debugging, modelled after the ALC880 test
6154 * configuration.
6155 */
6156#ifdef CONFIG_SND_DEBUG
6157static hda_nid_t alc260_test_dac_nids[1] = {
6158 0x02,
6159};
6160static hda_nid_t alc260_test_adc_nids[2] = {
6161 0x04, 0x05,
6162};
a1e8d2da 6163/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6164 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6165 * is NID 0x04.
17e7aec6 6166 */
a1e8d2da
JW
6167static struct hda_input_mux alc260_test_capture_sources[2] = {
6168 {
6169 .num_items = 7,
6170 .items = {
6171 { "MIC1 pin", 0x0 },
6172 { "MIC2 pin", 0x1 },
6173 { "LINE1 pin", 0x2 },
6174 { "LINE2 pin", 0x3 },
6175 { "CD pin", 0x4 },
6176 { "LINE-OUT pin", 0x5 },
6177 { "HP-OUT pin", 0x6 },
6178 },
6179 },
6180 {
6181 .num_items = 8,
6182 .items = {
6183 { "MIC1 pin", 0x0 },
6184 { "MIC2 pin", 0x1 },
6185 { "LINE1 pin", 0x2 },
6186 { "LINE2 pin", 0x3 },
6187 { "CD pin", 0x4 },
6188 { "Mixer", 0x5 },
6189 { "LINE-OUT pin", 0x6 },
6190 { "HP-OUT pin", 0x7 },
6191 },
7cf51e48
JW
6192 },
6193};
6194static struct snd_kcontrol_new alc260_test_mixer[] = {
6195 /* Output driver widgets */
6196 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6197 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6198 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6199 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6200 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6201 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6202
a1e8d2da
JW
6203 /* Modes for retasking pin widgets
6204 * Note: the ALC260 doesn't seem to act on requests to enable mic
6205 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6206 * mention this restriction. At this stage it's not clear whether
6207 * this behaviour is intentional or is a hardware bug in chip
6208 * revisions available at least up until early 2006. Therefore for
6209 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6210 * choices, but if it turns out that the lack of mic bias for these
6211 * NIDs is intentional we could change their modes from
6212 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6213 */
7cf51e48
JW
6214 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6215 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6216 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6217 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6218 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6219 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6220
6221 /* Loopback mixer controls */
6222 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6223 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6224 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6225 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6226 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6227 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6228 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6229 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6230 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6231 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6232 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6233 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6234 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6235 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6236
6237 /* Controls for GPIO pins, assuming they are configured as outputs */
6238 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6239 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6240 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6241 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6242
92621f13
JW
6243 /* Switches to allow the digital IO pins to be enabled. The datasheet
6244 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6245 * make this output available should provide clarification.
92621f13
JW
6246 */
6247 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6248 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6249
f8225f6d
JW
6250 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6251 * this output to turn on an external amplifier.
6252 */
6253 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6254 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6255
7cf51e48
JW
6256 { } /* end */
6257};
6258static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6259 /* Enable all GPIOs as outputs with an initial value of 0 */
6260 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6261 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6262 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6263
7cf51e48
JW
6264 /* Enable retasking pins as output, initially without power amp */
6265 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6266 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6269 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6270 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6271
92621f13
JW
6272 /* Disable digital (SPDIF) pins initially, but users can enable
6273 * them via a mixer switch. In the case of SPDIF-out, this initverb
6274 * payload also sets the generation to 0, output to be in "consumer"
6275 * PCM format, copyright asserted, no pre-emphasis and no validity
6276 * control.
6277 */
7cf51e48
JW
6278 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6279 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6280
ea1fb29a 6281 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6282 * OUT1 sum bus when acting as an output.
6283 */
6284 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6285 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6286 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6287 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6288
6289 /* Start with output sum widgets muted and their output gains at min */
6290 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6292 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6293 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6294 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6295 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6296 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6297 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6298 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6299
cdcd9268
JW
6300 /* Unmute retasking pin widget output buffers since the default
6301 * state appears to be output. As the pin mode is changed by the
6302 * user the pin mode control will take care of enabling the pin's
6303 * input/output buffers as needed.
6304 */
7cf51e48
JW
6305 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6308 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6309 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6310 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6311 /* Also unmute the mono-out pin widget */
6312 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6313
7cf51e48
JW
6314 /* Mute capture amp left and right */
6315 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6316 /* Set ADC connection select to match default mixer setting (mic1
6317 * pin)
7cf51e48
JW
6318 */
6319 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6320
6321 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6322 * set ADC connection to mic1 pin
7cf51e48
JW
6323 */
6324 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6325 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6326
6327 /* Mute all inputs to mixer widget (even unconnected ones) */
6328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6336
6337 { }
6338};
6339#endif
6340
6330079f
TI
6341#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6342#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6343
a3bcba38
TI
6344#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6345#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6346
df694daa
KY
6347/*
6348 * for BIOS auto-configuration
6349 */
16ded525 6350
df694daa 6351static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6352 const char *pfx, int *vol_bits)
df694daa
KY
6353{
6354 hda_nid_t nid_vol;
6355 unsigned long vol_val, sw_val;
df694daa
KY
6356 int err;
6357
6358 if (nid >= 0x0f && nid < 0x11) {
6359 nid_vol = nid - 0x7;
6360 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6361 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6362 } else if (nid == 0x11) {
6363 nid_vol = nid - 0x7;
6364 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6365 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6366 } else if (nid >= 0x12 && nid <= 0x15) {
6367 nid_vol = 0x08;
6368 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6369 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6370 } else
6371 return 0; /* N/A */
ea1fb29a 6372
863b4518
TI
6373 if (!(*vol_bits & (1 << nid_vol))) {
6374 /* first control for the volume widget */
0afe5f89 6375 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6376 if (err < 0)
6377 return err;
6378 *vol_bits |= (1 << nid_vol);
6379 }
0afe5f89 6380 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6381 if (err < 0)
df694daa
KY
6382 return err;
6383 return 1;
6384}
6385
6386/* add playback controls from the parsed DAC table */
6387static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6388 const struct auto_pin_cfg *cfg)
6389{
6390 hda_nid_t nid;
6391 int err;
863b4518 6392 int vols = 0;
df694daa
KY
6393
6394 spec->multiout.num_dacs = 1;
6395 spec->multiout.dac_nids = spec->private_dac_nids;
6396 spec->multiout.dac_nids[0] = 0x02;
6397
6398 nid = cfg->line_out_pins[0];
6399 if (nid) {
23112d6d
TI
6400 const char *pfx;
6401 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6402 pfx = "Master";
6403 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6404 pfx = "Speaker";
6405 else
6406 pfx = "Front";
6407 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6408 if (err < 0)
6409 return err;
6410 }
6411
82bc955f 6412 nid = cfg->speaker_pins[0];
df694daa 6413 if (nid) {
863b4518 6414 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6415 if (err < 0)
6416 return err;
6417 }
6418
eb06ed8f 6419 nid = cfg->hp_pins[0];
df694daa 6420 if (nid) {
863b4518
TI
6421 err = alc260_add_playback_controls(spec, nid, "Headphone",
6422 &vols);
df694daa
KY
6423 if (err < 0)
6424 return err;
6425 }
f12ab1e0 6426 return 0;
df694daa
KY
6427}
6428
6429/* create playback/capture controls for input pins */
05f5f477 6430static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6431 const struct auto_pin_cfg *cfg)
6432{
05f5f477 6433 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6434}
6435
6436static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6437 hda_nid_t nid, int pin_type,
6438 int sel_idx)
6439{
f6c7e546 6440 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6441 /* need the manual connection? */
6442 if (nid >= 0x12) {
6443 int idx = nid - 0x12;
6444 snd_hda_codec_write(codec, idx + 0x0b, 0,
6445 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6446 }
6447}
6448
6449static void alc260_auto_init_multi_out(struct hda_codec *codec)
6450{
6451 struct alc_spec *spec = codec->spec;
6452 hda_nid_t nid;
6453
f12ab1e0 6454 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6455 if (nid) {
6456 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6457 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6458 }
ea1fb29a 6459
82bc955f 6460 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6461 if (nid)
6462 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6463
eb06ed8f 6464 nid = spec->autocfg.hp_pins[0];
df694daa 6465 if (nid)
baba8ee9 6466 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6467}
df694daa
KY
6468
6469#define ALC260_PIN_CD_NID 0x16
6470static void alc260_auto_init_analog_input(struct hda_codec *codec)
6471{
6472 struct alc_spec *spec = codec->spec;
6473 int i;
6474
6475 for (i = 0; i < AUTO_PIN_LAST; i++) {
6476 hda_nid_t nid = spec->autocfg.input_pins[i];
6477 if (nid >= 0x12) {
23f0c048 6478 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6479 if (nid != ALC260_PIN_CD_NID &&
6480 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6481 snd_hda_codec_write(codec, nid, 0,
6482 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6483 AMP_OUT_MUTE);
6484 }
6485 }
6486}
6487
6488/*
6489 * generic initialization of ADC, input mixers and output mixers
6490 */
6491static struct hda_verb alc260_volume_init_verbs[] = {
6492 /*
6493 * Unmute ADC0-1 and set the default input to mic-in
6494 */
6495 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6496 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6497 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6498 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6499
df694daa
KY
6500 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6501 * mixer widget
f12ab1e0
TI
6502 * Note: PASD motherboards uses the Line In 2 as the input for
6503 * front panel mic (mic 2)
df694daa
KY
6504 */
6505 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6506 /* mute analog inputs */
6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6511 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6512
6513 /*
6514 * Set up output mixers (0x08 - 0x0a)
6515 */
6516 /* set vol=0 to output mixers */
6517 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6519 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6520 /* set up input amps for analog loopback */
6521 /* Amp Indices: DAC = 0, mixer = 1 */
6522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6523 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6524 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6525 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6526 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6527 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6528
df694daa
KY
6529 { }
6530};
6531
6532static int alc260_parse_auto_config(struct hda_codec *codec)
6533{
6534 struct alc_spec *spec = codec->spec;
df694daa
KY
6535 int err;
6536 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6537
f12ab1e0
TI
6538 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6539 alc260_ignore);
6540 if (err < 0)
df694daa 6541 return err;
f12ab1e0
TI
6542 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6543 if (err < 0)
4a471b7d 6544 return err;
603c4019 6545 if (!spec->kctls.list)
df694daa 6546 return 0; /* can't find valid BIOS pin config */
05f5f477 6547 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6548 if (err < 0)
df694daa
KY
6549 return err;
6550
6551 spec->multiout.max_channels = 2;
6552
0852d7a6 6553 if (spec->autocfg.dig_outs)
df694daa 6554 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6555 if (spec->kctls.list)
d88897ea 6556 add_mixer(spec, spec->kctls.list);
df694daa 6557
d88897ea 6558 add_verb(spec, alc260_volume_init_verbs);
df694daa 6559
a1e8d2da 6560 spec->num_mux_defs = 1;
61b9b9b1 6561 spec->input_mux = &spec->private_imux[0];
df694daa 6562
6227cdce 6563 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6564
df694daa
KY
6565 return 1;
6566}
6567
ae6b813a
TI
6568/* additional initialization for auto-configuration model */
6569static void alc260_auto_init(struct hda_codec *codec)
df694daa 6570{
f6c7e546 6571 struct alc_spec *spec = codec->spec;
df694daa
KY
6572 alc260_auto_init_multi_out(codec);
6573 alc260_auto_init_analog_input(codec);
f6c7e546 6574 if (spec->unsol_event)
7fb0d78f 6575 alc_inithook(codec);
df694daa
KY
6576}
6577
cb53c626
TI
6578#ifdef CONFIG_SND_HDA_POWER_SAVE
6579static struct hda_amp_list alc260_loopbacks[] = {
6580 { 0x07, HDA_INPUT, 0 },
6581 { 0x07, HDA_INPUT, 1 },
6582 { 0x07, HDA_INPUT, 2 },
6583 { 0x07, HDA_INPUT, 3 },
6584 { 0x07, HDA_INPUT, 4 },
6585 { } /* end */
6586};
6587#endif
6588
df694daa
KY
6589/*
6590 * ALC260 configurations
6591 */
f5fcc13c
TI
6592static const char *alc260_models[ALC260_MODEL_LAST] = {
6593 [ALC260_BASIC] = "basic",
6594 [ALC260_HP] = "hp",
6595 [ALC260_HP_3013] = "hp-3013",
2922c9af 6596 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6597 [ALC260_FUJITSU_S702X] = "fujitsu",
6598 [ALC260_ACER] = "acer",
bc9f98a9
KY
6599 [ALC260_WILL] = "will",
6600 [ALC260_REPLACER_672V] = "replacer",
cc959489 6601 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6602#ifdef CONFIG_SND_DEBUG
f5fcc13c 6603 [ALC260_TEST] = "test",
7cf51e48 6604#endif
f5fcc13c
TI
6605 [ALC260_AUTO] = "auto",
6606};
6607
6608static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6609 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6610 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6611 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6612 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6613 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6614 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6615 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6616 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6617 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6618 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6619 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6620 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6621 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6622 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6623 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6624 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6625 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6626 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6627 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6628 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6629 {}
6630};
6631
6632static struct alc_config_preset alc260_presets[] = {
6633 [ALC260_BASIC] = {
6634 .mixers = { alc260_base_output_mixer,
45bdd1c1 6635 alc260_input_mixer },
df694daa
KY
6636 .init_verbs = { alc260_init_verbs },
6637 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6638 .dac_nids = alc260_dac_nids,
f9e336f6 6639 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6640 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6641 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6642 .channel_mode = alc260_modes,
6643 .input_mux = &alc260_capture_source,
6644 },
6645 [ALC260_HP] = {
bec15c3a 6646 .mixers = { alc260_hp_output_mixer,
f9e336f6 6647 alc260_input_mixer },
bec15c3a
TI
6648 .init_verbs = { alc260_init_verbs,
6649 alc260_hp_unsol_verbs },
df694daa
KY
6650 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6651 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6652 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6653 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6654 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6655 .channel_mode = alc260_modes,
6656 .input_mux = &alc260_capture_source,
bec15c3a
TI
6657 .unsol_event = alc260_hp_unsol_event,
6658 .init_hook = alc260_hp_automute,
df694daa 6659 },
3f878308
KY
6660 [ALC260_HP_DC7600] = {
6661 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6662 alc260_input_mixer },
3f878308
KY
6663 .init_verbs = { alc260_init_verbs,
6664 alc260_hp_dc7600_verbs },
6665 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6666 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6667 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6668 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6669 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6670 .channel_mode = alc260_modes,
6671 .input_mux = &alc260_capture_source,
6672 .unsol_event = alc260_hp_3012_unsol_event,
6673 .init_hook = alc260_hp_3012_automute,
6674 },
df694daa
KY
6675 [ALC260_HP_3013] = {
6676 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6677 alc260_input_mixer },
bec15c3a
TI
6678 .init_verbs = { alc260_hp_3013_init_verbs,
6679 alc260_hp_3013_unsol_verbs },
df694daa
KY
6680 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6681 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6682 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6683 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6684 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6685 .channel_mode = alc260_modes,
6686 .input_mux = &alc260_capture_source,
bec15c3a
TI
6687 .unsol_event = alc260_hp_3013_unsol_event,
6688 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6689 },
6690 [ALC260_FUJITSU_S702X] = {
f9e336f6 6691 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6692 .init_verbs = { alc260_fujitsu_init_verbs },
6693 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6694 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6695 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6696 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6697 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6698 .channel_mode = alc260_modes,
a1e8d2da
JW
6699 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6700 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6701 },
0bfc90e9 6702 [ALC260_ACER] = {
f9e336f6 6703 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6704 .init_verbs = { alc260_acer_init_verbs },
6705 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6706 .dac_nids = alc260_dac_nids,
6707 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6708 .adc_nids = alc260_dual_adc_nids,
6709 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6710 .channel_mode = alc260_modes,
a1e8d2da
JW
6711 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6712 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6713 },
cc959489
MS
6714 [ALC260_FAVORIT100] = {
6715 .mixers = { alc260_favorit100_mixer },
6716 .init_verbs = { alc260_favorit100_init_verbs },
6717 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6718 .dac_nids = alc260_dac_nids,
6719 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6720 .adc_nids = alc260_dual_adc_nids,
6721 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6722 .channel_mode = alc260_modes,
6723 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6724 .input_mux = alc260_favorit100_capture_sources,
6725 },
bc9f98a9 6726 [ALC260_WILL] = {
f9e336f6 6727 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6728 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6729 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6730 .dac_nids = alc260_dac_nids,
6731 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6732 .adc_nids = alc260_adc_nids,
6733 .dig_out_nid = ALC260_DIGOUT_NID,
6734 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6735 .channel_mode = alc260_modes,
6736 .input_mux = &alc260_capture_source,
6737 },
6738 [ALC260_REPLACER_672V] = {
f9e336f6 6739 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6740 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6741 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6742 .dac_nids = alc260_dac_nids,
6743 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6744 .adc_nids = alc260_adc_nids,
6745 .dig_out_nid = ALC260_DIGOUT_NID,
6746 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6747 .channel_mode = alc260_modes,
6748 .input_mux = &alc260_capture_source,
6749 .unsol_event = alc260_replacer_672v_unsol_event,
6750 .init_hook = alc260_replacer_672v_automute,
6751 },
7cf51e48
JW
6752#ifdef CONFIG_SND_DEBUG
6753 [ALC260_TEST] = {
f9e336f6 6754 .mixers = { alc260_test_mixer },
7cf51e48
JW
6755 .init_verbs = { alc260_test_init_verbs },
6756 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6757 .dac_nids = alc260_test_dac_nids,
6758 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6759 .adc_nids = alc260_test_adc_nids,
6760 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6761 .channel_mode = alc260_modes,
a1e8d2da
JW
6762 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6763 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6764 },
6765#endif
df694daa
KY
6766};
6767
6768static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6769{
6770 struct alc_spec *spec;
df694daa 6771 int err, board_config;
1da177e4 6772
e560d8d8 6773 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6774 if (spec == NULL)
6775 return -ENOMEM;
6776
6777 codec->spec = spec;
6778
f5fcc13c
TI
6779 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6780 alc260_models,
6781 alc260_cfg_tbl);
6782 if (board_config < 0) {
9a11f1aa 6783 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6784 codec->chip_name);
df694daa 6785 board_config = ALC260_AUTO;
16ded525 6786 }
1da177e4 6787
df694daa
KY
6788 if (board_config == ALC260_AUTO) {
6789 /* automatic parse from the BIOS config */
6790 err = alc260_parse_auto_config(codec);
6791 if (err < 0) {
6792 alc_free(codec);
6793 return err;
f12ab1e0 6794 } else if (!err) {
9c7f852e
TI
6795 printk(KERN_INFO
6796 "hda_codec: Cannot set up configuration "
6797 "from BIOS. Using base mode...\n");
df694daa
KY
6798 board_config = ALC260_BASIC;
6799 }
a9430dd8 6800 }
e9edcee0 6801
680cd536
KK
6802 err = snd_hda_attach_beep_device(codec, 0x1);
6803 if (err < 0) {
6804 alc_free(codec);
6805 return err;
6806 }
6807
df694daa 6808 if (board_config != ALC260_AUTO)
e9c364c0 6809 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 6810
1da177e4
LT
6811 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6812 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6813
a3bcba38
TI
6814 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6815 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6816
4ef0ef19
TI
6817 if (!spec->adc_nids && spec->input_mux) {
6818 /* check whether NID 0x04 is valid */
6819 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 6820 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
6821 /* get type */
6822 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6823 spec->adc_nids = alc260_adc_nids_alt;
6824 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6825 } else {
6826 spec->adc_nids = alc260_adc_nids;
6827 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6828 }
6829 }
b59bdf3b 6830 set_capture_mixer(codec);
45bdd1c1 6831 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6832
2134ea4f
TI
6833 spec->vmaster_nid = 0x08;
6834
1da177e4 6835 codec->patch_ops = alc_patch_ops;
df694daa 6836 if (board_config == ALC260_AUTO)
ae6b813a 6837 spec->init_hook = alc260_auto_init;
cb53c626
TI
6838#ifdef CONFIG_SND_HDA_POWER_SAVE
6839 if (!spec->loopback.amplist)
6840 spec->loopback.amplist = alc260_loopbacks;
6841#endif
1da177e4
LT
6842
6843 return 0;
6844}
6845
e9edcee0 6846
1da177e4 6847/*
4953550a 6848 * ALC882/883/885/888/889 support
1da177e4
LT
6849 *
6850 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6851 * configuration. Each pin widget can choose any input DACs and a mixer.
6852 * Each ADC is connected from a mixer of all inputs. This makes possible
6853 * 6-channel independent captures.
6854 *
6855 * In addition, an independent DAC for the multi-playback (not used in this
6856 * driver yet).
6857 */
df694daa
KY
6858#define ALC882_DIGOUT_NID 0x06
6859#define ALC882_DIGIN_NID 0x0a
4953550a
TI
6860#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6861#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6862#define ALC1200_DIGOUT_NID 0x10
6863
1da177e4 6864
d2a6d7dc 6865static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6866 { 8, NULL }
6867};
6868
4953550a 6869/* DACs */
1da177e4
LT
6870static hda_nid_t alc882_dac_nids[4] = {
6871 /* front, rear, clfe, rear_surr */
6872 0x02, 0x03, 0x04, 0x05
6873};
4953550a 6874#define alc883_dac_nids alc882_dac_nids
1da177e4 6875
4953550a 6876/* ADCs */
df694daa
KY
6877#define alc882_adc_nids alc880_adc_nids
6878#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
6879#define alc883_adc_nids alc882_adc_nids_alt
6880static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6881static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6882#define alc889_adc_nids alc880_adc_nids
1da177e4 6883
e1406348
TI
6884static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6885static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
6886#define alc883_capsrc_nids alc882_capsrc_nids_alt
6887static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6888#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 6889
1da177e4
LT
6890/* input MUX */
6891/* FIXME: should be a matrix-type input source selection */
6892
6893static struct hda_input_mux alc882_capture_source = {
6894 .num_items = 4,
6895 .items = {
6896 { "Mic", 0x0 },
6897 { "Front Mic", 0x1 },
6898 { "Line", 0x2 },
6899 { "CD", 0x4 },
6900 },
6901};
41d5545d 6902
4953550a
TI
6903#define alc883_capture_source alc882_capture_source
6904
87a8c370
JK
6905static struct hda_input_mux alc889_capture_source = {
6906 .num_items = 3,
6907 .items = {
6908 { "Front Mic", 0x0 },
6909 { "Mic", 0x3 },
6910 { "Line", 0x2 },
6911 },
6912};
6913
41d5545d
KS
6914static struct hda_input_mux mb5_capture_source = {
6915 .num_items = 3,
6916 .items = {
6917 { "Mic", 0x1 },
6918 { "Line", 0x2 },
6919 { "CD", 0x4 },
6920 },
6921};
6922
e458b1fa
LY
6923static struct hda_input_mux macmini3_capture_source = {
6924 .num_items = 2,
6925 .items = {
6926 { "Line", 0x2 },
6927 { "CD", 0x4 },
6928 },
6929};
6930
4953550a
TI
6931static struct hda_input_mux alc883_3stack_6ch_intel = {
6932 .num_items = 4,
6933 .items = {
6934 { "Mic", 0x1 },
6935 { "Front Mic", 0x0 },
6936 { "Line", 0x2 },
6937 { "CD", 0x4 },
6938 },
6939};
6940
6941static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6942 .num_items = 2,
6943 .items = {
6944 { "Mic", 0x1 },
6945 { "Line", 0x2 },
6946 },
6947};
6948
6949static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6950 .num_items = 4,
6951 .items = {
6952 { "Mic", 0x0 },
6953 { "iMic", 0x1 },
6954 { "Line", 0x2 },
6955 { "CD", 0x4 },
6956 },
6957};
6958
6959static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6960 .num_items = 2,
6961 .items = {
6962 { "Mic", 0x0 },
6963 { "Int Mic", 0x1 },
6964 },
6965};
6966
6967static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6968 .num_items = 3,
6969 .items = {
6970 { "Mic", 0x0 },
6971 { "Front Mic", 0x1 },
6972 { "Line", 0x4 },
6973 },
6974};
6975
6976static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6977 .num_items = 2,
6978 .items = {
6979 { "Mic", 0x0 },
6980 { "Line", 0x2 },
6981 },
6982};
6983
6984static struct hda_input_mux alc889A_mb31_capture_source = {
6985 .num_items = 2,
6986 .items = {
6987 { "Mic", 0x0 },
6988 /* Front Mic (0x01) unused */
6989 { "Line", 0x2 },
6990 /* Line 2 (0x03) unused */
af901ca1 6991 /* CD (0x04) unused? */
4953550a
TI
6992 },
6993};
6994
6995/*
6996 * 2ch mode
6997 */
6998static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6999 { 2, NULL }
7000};
7001
272a527c
KY
7002/*
7003 * 2ch mode
7004 */
7005static struct hda_verb alc882_3ST_ch2_init[] = {
7006 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7007 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7008 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7009 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7010 { } /* end */
7011};
7012
4953550a
TI
7013/*
7014 * 4ch mode
7015 */
7016static struct hda_verb alc882_3ST_ch4_init[] = {
7017 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7018 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7019 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7020 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7021 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7022 { } /* end */
7023};
7024
272a527c
KY
7025/*
7026 * 6ch mode
7027 */
7028static struct hda_verb alc882_3ST_ch6_init[] = {
7029 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7030 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7031 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7033 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7034 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7035 { } /* end */
7036};
7037
4953550a 7038static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7039 { 2, alc882_3ST_ch2_init },
4953550a 7040 { 4, alc882_3ST_ch4_init },
272a527c
KY
7041 { 6, alc882_3ST_ch6_init },
7042};
7043
4953550a
TI
7044#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7045
a65cc60f 7046/*
7047 * 2ch mode
7048 */
7049static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7050 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7052 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7053 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7054 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7055 { } /* end */
7056};
7057
7058/*
7059 * 4ch mode
7060 */
7061static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7062 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7063 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7064 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7065 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7066 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7067 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7068 { } /* end */
7069};
7070
7071/*
7072 * 6ch mode
7073 */
7074static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7075 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7076 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7077 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7078 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7079 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7080 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7081 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7082 { } /* end */
7083};
7084
7085static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7086 { 2, alc883_3ST_ch2_clevo_init },
7087 { 4, alc883_3ST_ch4_clevo_init },
7088 { 6, alc883_3ST_ch6_clevo_init },
7089};
7090
7091
df694daa
KY
7092/*
7093 * 6ch mode
7094 */
7095static struct hda_verb alc882_sixstack_ch6_init[] = {
7096 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7097 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7098 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7099 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7100 { } /* end */
7101};
7102
7103/*
7104 * 8ch mode
7105 */
7106static struct hda_verb alc882_sixstack_ch8_init[] = {
7107 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7108 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7109 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7110 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7111 { } /* end */
7112};
7113
7114static struct hda_channel_mode alc882_sixstack_modes[2] = {
7115 { 6, alc882_sixstack_ch6_init },
7116 { 8, alc882_sixstack_ch8_init },
7117};
7118
76e6f5a9
RH
7119
7120/* Macbook Air 2,1 */
7121
7122static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7123 { 2, NULL },
7124};
7125
87350ad0 7126/*
def319f9 7127 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7128 */
7129
7130/*
7131 * 2ch mode
7132 */
7133static struct hda_verb alc885_mbp_ch2_init[] = {
7134 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7135 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7136 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7137 { } /* end */
7138};
7139
7140/*
a3f730af 7141 * 4ch mode
87350ad0 7142 */
a3f730af 7143static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7144 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7145 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7146 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7147 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7148 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7149 { } /* end */
7150};
7151
a3f730af 7152static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7153 { 2, alc885_mbp_ch2_init },
a3f730af 7154 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7155};
7156
92b9de83
KS
7157/*
7158 * 2ch
7159 * Speakers/Woofer/HP = Front
7160 * LineIn = Input
7161 */
7162static struct hda_verb alc885_mb5_ch2_init[] = {
7163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7165 { } /* end */
7166};
7167
7168/*
7169 * 6ch mode
7170 * Speakers/HP = Front
7171 * Woofer = LFE
7172 * LineIn = Surround
7173 */
7174static struct hda_verb alc885_mb5_ch6_init[] = {
7175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7176 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7178 { } /* end */
7179};
7180
7181static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7182 { 2, alc885_mb5_ch2_init },
7183 { 6, alc885_mb5_ch6_init },
7184};
87350ad0 7185
d01aecdf 7186#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7187
7188/*
7189 * 2ch mode
7190 */
7191static struct hda_verb alc883_4ST_ch2_init[] = {
7192 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7193 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7194 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7195 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7198 { } /* end */
7199};
7200
7201/*
7202 * 4ch mode
7203 */
7204static struct hda_verb alc883_4ST_ch4_init[] = {
7205 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7206 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7207 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7208 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7209 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7210 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7211 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7212 { } /* end */
7213};
7214
7215/*
7216 * 6ch mode
7217 */
7218static struct hda_verb alc883_4ST_ch6_init[] = {
7219 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7220 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7221 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7222 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7223 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7224 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7225 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7226 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7227 { } /* end */
7228};
7229
7230/*
7231 * 8ch mode
7232 */
7233static struct hda_verb alc883_4ST_ch8_init[] = {
7234 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7235 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7236 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7237 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7238 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7239 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7240 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7241 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7242 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7243 { } /* end */
7244};
7245
7246static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7247 { 2, alc883_4ST_ch2_init },
7248 { 4, alc883_4ST_ch4_init },
7249 { 6, alc883_4ST_ch6_init },
7250 { 8, alc883_4ST_ch8_init },
7251};
7252
7253
7254/*
7255 * 2ch mode
7256 */
7257static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7258 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7259 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7260 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7261 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7262 { } /* end */
7263};
7264
7265/*
7266 * 4ch mode
7267 */
7268static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7269 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7270 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7273 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7274 { } /* end */
7275};
7276
7277/*
7278 * 6ch mode
7279 */
7280static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7281 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7282 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7283 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7284 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7285 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7286 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7287 { } /* end */
7288};
7289
7290static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7291 { 2, alc883_3ST_ch2_intel_init },
7292 { 4, alc883_3ST_ch4_intel_init },
7293 { 6, alc883_3ST_ch6_intel_init },
7294};
7295
dd7714c9
WF
7296/*
7297 * 2ch mode
7298 */
7299static struct hda_verb alc889_ch2_intel_init[] = {
7300 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7301 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7302 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7303 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7304 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7305 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7306 { } /* end */
7307};
7308
87a8c370
JK
7309/*
7310 * 6ch mode
7311 */
7312static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7313 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7314 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7315 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7316 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7317 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7318 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7319 { } /* end */
7320};
7321
7322/*
7323 * 8ch mode
7324 */
7325static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7326 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7327 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7328 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7329 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7330 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7331 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7332 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7333 { } /* end */
7334};
7335
dd7714c9
WF
7336static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7337 { 2, alc889_ch2_intel_init },
87a8c370
JK
7338 { 6, alc889_ch6_intel_init },
7339 { 8, alc889_ch8_intel_init },
7340};
7341
4953550a
TI
7342/*
7343 * 6ch mode
7344 */
7345static struct hda_verb alc883_sixstack_ch6_init[] = {
7346 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7347 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7348 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7349 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7350 { } /* end */
7351};
7352
7353/*
7354 * 8ch mode
7355 */
7356static struct hda_verb alc883_sixstack_ch8_init[] = {
7357 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7358 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7359 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7360 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7361 { } /* end */
7362};
7363
7364static struct hda_channel_mode alc883_sixstack_modes[2] = {
7365 { 6, alc883_sixstack_ch6_init },
7366 { 8, alc883_sixstack_ch8_init },
7367};
7368
7369
1da177e4
LT
7370/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7371 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7372 */
c8b6bf9b 7373static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7374 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7375 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7377 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7379 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7380 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7381 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7382 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7383 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7390 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7392 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7393 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7395 { } /* end */
7396};
7397
76e6f5a9
RH
7398/* Macbook Air 2,1 same control for HP and internal Speaker */
7399
7400static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7401 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7402 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7403 { }
7404};
7405
7406
87350ad0 7407static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7408 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7409 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7410 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7411 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7412 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7414 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7415 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7416 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7417 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7418 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7419 { } /* end */
7420};
41d5545d
KS
7421
7422static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7423 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7424 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7426 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7427 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7428 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7429 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7430 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
41d5545d
KS
7431 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7432 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7434 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7435 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7436 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7437 { } /* end */
7438};
92b9de83 7439
e458b1fa
LY
7440static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7441 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7442 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7443 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7444 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7445 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7446 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7448 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7450 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7451 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7452 { } /* end */
7453};
7454
4b7e1803
JM
7455static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7456 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7457 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
7458 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7459 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7461 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7463 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7464 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7465 { } /* end */
7466};
7467
7468
bdd148a3
KY
7469static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7471 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7472 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7473 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7475 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7477 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7479 { } /* end */
7480};
7481
272a527c
KY
7482static struct snd_kcontrol_new alc882_targa_mixer[] = {
7483 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7486 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7487 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7492 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7493 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7494 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7495 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7496 { } /* end */
7497};
7498
7499/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7500 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7501 */
7502static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7504 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7506 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7507 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7508 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7509 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7510 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7511 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7512 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7516 { } /* end */
7517};
7518
914759b7
TI
7519static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7521 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7522 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7523 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7524 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7525 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7526 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7527 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7528 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7529 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7530 { } /* end */
7531};
7532
df694daa
KY
7533static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7534 {
7535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7536 .name = "Channel Mode",
7537 .info = alc_ch_mode_info,
7538 .get = alc_ch_mode_get,
7539 .put = alc_ch_mode_put,
7540 },
7541 { } /* end */
7542};
7543
4953550a 7544static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7545 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7548 /* Rear mixer */
05acb863
TI
7549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7551 /* CLFE mixer */
05acb863
TI
7552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7554 /* Side mixer */
05acb863
TI
7555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7557
e9edcee0 7558 /* Front Pin: output 0 (0x0c) */
05acb863 7559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7561 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7562 /* Rear Pin: output 1 (0x0d) */
05acb863 7563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7565 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7566 /* CLFE Pin: output 2 (0x0e) */
05acb863 7567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7569 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7570 /* Side Pin: output 3 (0x0f) */
05acb863 7571 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7572 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7573 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7574 /* Mic (rear) pin: input vref at 80% */
16ded525 7575 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7576 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7577 /* Front Mic pin: input vref at 80% */
16ded525 7578 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7579 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7580 /* Line In pin: input */
05acb863 7581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7583 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7587 /* CD pin widget for input */
05acb863 7588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7589
7590 /* FIXME: use matrix-type input source selection */
7591 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7592 /* Input mixer2 */
05acb863 7593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7594 /* Input mixer3 */
05acb863 7595 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7596 /* ADC2: mute amp left and right */
7597 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7598 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7599 /* ADC3: mute amp left and right */
7600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7601 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7602
7603 { }
7604};
7605
4953550a
TI
7606static struct hda_verb alc882_adc1_init_verbs[] = {
7607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7612 /* ADC1: mute amp left and right */
7613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7614 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7615 { }
7616};
7617
4b146cb0
TI
7618static struct hda_verb alc882_eapd_verbs[] = {
7619 /* change to EAPD mode */
7620 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7621 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7622 { }
4b146cb0
TI
7623};
7624
87a8c370
JK
7625static struct hda_verb alc889_eapd_verbs[] = {
7626 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7627 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7628 { }
7629};
7630
6732bd0d
WF
7631static struct hda_verb alc_hp15_unsol_verbs[] = {
7632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7634 {}
7635};
87a8c370
JK
7636
7637static struct hda_verb alc885_init_verbs[] = {
7638 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7641 /* Rear mixer */
88102f3f
KY
7642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7644 /* CLFE mixer */
88102f3f
KY
7645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7646 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7647 /* Side mixer */
88102f3f
KY
7648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7649 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7650
7651 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7655 /* Front Pin: output 0 (0x0c) */
7656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7657 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7658 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7659 /* Rear Pin: output 1 (0x0d) */
7660 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7662 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7663 /* CLFE Pin: output 2 (0x0e) */
7664 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7666 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7667 /* Side Pin: output 3 (0x0f) */
7668 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7669 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7671 /* Mic (rear) pin: input vref at 80% */
7672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7673 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7674 /* Front Mic pin: input vref at 80% */
7675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7677 /* Line In pin: input */
7678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7680
7681 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7682 /* Input mixer1 */
88102f3f 7683 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7684 /* Input mixer2 */
7685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7686 /* Input mixer3 */
88102f3f 7687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7688 /* ADC2: mute amp left and right */
7689 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7690 /* ADC3: mute amp left and right */
7691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7692
7693 { }
7694};
7695
7696static struct hda_verb alc885_init_input_verbs[] = {
7697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7698 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7699 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7700 { }
7701};
7702
7703
7704/* Unmute Selector 24h and set the default input to front mic */
7705static struct hda_verb alc889_init_input_verbs[] = {
7706 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7708 { }
7709};
7710
7711
4953550a
TI
7712#define alc883_init_verbs alc882_base_init_verbs
7713
9102cd1c
TD
7714/* Mac Pro test */
7715static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7716 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7717 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7719 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7720 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7721 /* FIXME: this looks suspicious...
d355c82a
JK
7722 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7723 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7724 */
9102cd1c
TD
7725 { } /* end */
7726};
7727
7728static struct hda_verb alc882_macpro_init_verbs[] = {
7729 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7733 /* Front Pin: output 0 (0x0c) */
7734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7736 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7737 /* Front Mic pin: input vref at 80% */
7738 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7740 /* Speaker: output */
7741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7743 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7744 /* Headphone output (output 0 - 0x0c) */
7745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7747 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7748
7749 /* FIXME: use matrix-type input source selection */
7750 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7751 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7753 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7756 /* Input mixer2 */
7757 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7758 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7759 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7760 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7761 /* Input mixer3 */
7762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7763 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7766 /* ADC1: mute amp left and right */
7767 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7768 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7769 /* ADC2: mute amp left and right */
7770 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7771 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7772 /* ADC3: mute amp left and right */
7773 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7774 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7775
7776 { }
7777};
f12ab1e0 7778
41d5545d
KS
7779/* Macbook 5,1 */
7780static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7781 /* DACs */
7782 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7783 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7784 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7786 /* Front mixer */
41d5545d
KS
7787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7790 /* Surround mixer */
7791 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7792 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7793 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7794 /* LFE mixer */
7795 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7796 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7798 /* HP mixer */
7799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7802 /* Front Pin (0x0c) */
41d5545d
KS
7803 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
7805 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7806 /* LFE Pin (0x0e) */
7807 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7809 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7810 /* HP Pin (0x0f) */
41d5545d
KS
7811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 7813 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 7814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
7815 /* Front Mic pin: input vref at 80% */
7816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7818 /* Line In pin */
7819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7821
7822 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7823 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7824 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7825 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7826 { }
7827};
7828
e458b1fa
LY
7829/* Macmini 3,1 */
7830static struct hda_verb alc885_macmini3_init_verbs[] = {
7831 /* DACs */
7832 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7833 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7834 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7835 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7836 /* Front mixer */
7837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7840 /* Surround mixer */
7841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7844 /* LFE mixer */
7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7848 /* HP mixer */
7849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7852 /* Front Pin (0x0c) */
7853 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7854 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7855 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7856 /* LFE Pin (0x0e) */
7857 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7859 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7860 /* HP Pin (0x0f) */
7861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7862 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7863 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7864 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7865 /* Line In pin */
7866 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7868
7869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7873 { }
7874};
7875
76e6f5a9
RH
7876
7877static struct hda_verb alc885_mba21_init_verbs[] = {
7878 /*Internal and HP Speaker Mixer*/
7879 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7880 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7881 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7882 /*Internal Speaker Pin (0x0c)*/
7883 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7884 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7885 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7886 /* HP Pin: output 0 (0x0e) */
7887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7890 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7891 /* Line in (is hp when jack connected)*/
7892 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7893 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7894
7895 { }
7896 };
7897
7898
87350ad0
TI
7899/* Macbook Pro rev3 */
7900static struct hda_verb alc885_mbp3_init_verbs[] = {
7901 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7905 /* Rear mixer */
7906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
7909 /* HP mixer */
7910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
7913 /* Front Pin: output 0 (0x0c) */
7914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7915 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7916 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 7917 /* HP Pin: output 0 (0x0e) */
87350ad0 7918 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
7919 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7920 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
7921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7922 /* Mic (rear) pin: input vref at 80% */
7923 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7925 /* Front Mic pin: input vref at 80% */
7926 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7927 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7928 /* Line In pin: use output 1 when in LineOut mode */
7929 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7930 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7931 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7932
7933 /* FIXME: use matrix-type input source selection */
7934 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7935 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7936 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7937 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7938 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7940 /* Input mixer2 */
7941 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7942 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7943 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7944 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7945 /* Input mixer3 */
7946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7947 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7948 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7950 /* ADC1: mute amp left and right */
7951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7952 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7953 /* ADC2: mute amp left and right */
7954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7955 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7956 /* ADC3: mute amp left and right */
7957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7958 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7959
7960 { }
7961};
7962
4b7e1803
JM
7963/* iMac 9,1 */
7964static struct hda_verb alc885_imac91_init_verbs[] = {
7965 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7969 /* Rear mixer */
7970 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7971 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7972 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7973 /* HP Pin: output 0 (0x0c) */
7974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7976 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7977 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7978 /* Internal Speakers: output 0 (0x0d) */
7979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7980 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7982 /* Mic (rear) pin: input vref at 80% */
7983 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7984 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7985 /* Front Mic pin: input vref at 80% */
7986 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7987 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7988 /* Line In pin: use output 1 when in LineOut mode */
7989 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7990 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7991 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7992
7993 /* FIXME: use matrix-type input source selection */
7994 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7995 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7999 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8000 /* Input mixer2 */
8001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8004 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8005 /* Input mixer3 */
8006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8010 /* ADC1: mute amp left and right */
8011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8012 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8013 /* ADC2: mute amp left and right */
8014 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8015 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8016 /* ADC3: mute amp left and right */
8017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8018 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8019
8020 { }
8021};
8022
c54728d8
NF
8023/* iMac 24 mixer. */
8024static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8025 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8026 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8027 { } /* end */
8028};
8029
8030/* iMac 24 init verbs. */
8031static struct hda_verb alc885_imac24_init_verbs[] = {
8032 /* Internal speakers: output 0 (0x0c) */
8033 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8034 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8035 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8036 /* Internal speakers: output 0 (0x0c) */
8037 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8039 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8040 /* Headphone: output 0 (0x0c) */
8041 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8042 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8043 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8045 /* Front Mic: input vref at 80% */
8046 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8047 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8048 { }
8049};
8050
8051/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8052static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8053{
a9fd4f3f 8054 struct alc_spec *spec = codec->spec;
c54728d8 8055
a9fd4f3f
TI
8056 spec->autocfg.hp_pins[0] = 0x14;
8057 spec->autocfg.speaker_pins[0] = 0x18;
8058 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8059}
8060
9d54f08b
TI
8061#define alc885_mb5_setup alc885_imac24_setup
8062#define alc885_macmini3_setup alc885_imac24_setup
8063
76e6f5a9
RH
8064/* Macbook Air 2,1 */
8065static void alc885_mba21_setup(struct hda_codec *codec)
8066{
8067 struct alc_spec *spec = codec->spec;
8068
8069 spec->autocfg.hp_pins[0] = 0x14;
8070 spec->autocfg.speaker_pins[0] = 0x18;
8071}
8072
8073
8074
4f5d1706 8075static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8076{
a9fd4f3f 8077 struct alc_spec *spec = codec->spec;
87350ad0 8078
a9fd4f3f
TI
8079 spec->autocfg.hp_pins[0] = 0x15;
8080 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8081}
8082
9d54f08b 8083static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8084{
9d54f08b 8085 struct alc_spec *spec = codec->spec;
4b7e1803 8086
9d54f08b
TI
8087 spec->autocfg.hp_pins[0] = 0x14;
8088 spec->autocfg.speaker_pins[0] = 0x15;
8089 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8090}
87350ad0 8091
272a527c
KY
8092static struct hda_verb alc882_targa_verbs[] = {
8093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8095
8096 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8098
272a527c
KY
8099 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8100 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8102
8103 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8104 { } /* end */
8105};
8106
8107/* toggle speaker-output according to the hp-jack state */
8108static void alc882_targa_automute(struct hda_codec *codec)
8109{
a9fd4f3f
TI
8110 struct alc_spec *spec = codec->spec;
8111 alc_automute_amp(codec);
82beb8fd 8112 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8113 spec->jack_present ? 1 : 3);
8114}
8115
4f5d1706 8116static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8117{
8118 struct alc_spec *spec = codec->spec;
8119
8120 spec->autocfg.hp_pins[0] = 0x14;
8121 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8122}
8123
8124static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8125{
a9fd4f3f 8126 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8127 alc882_targa_automute(codec);
272a527c
KY
8128}
8129
8130static struct hda_verb alc882_asus_a7j_verbs[] = {
8131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8132 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8133
8134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8135 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8136 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8137
272a527c
KY
8138 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8139 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8140 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8141
8142 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8143 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8144 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8145 { } /* end */
8146};
8147
914759b7
TI
8148static struct hda_verb alc882_asus_a7m_verbs[] = {
8149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8150 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8151
8152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8154 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8155
914759b7
TI
8156 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8157 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8158 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8159
8160 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8161 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8163 { } /* end */
8164};
8165
9102cd1c
TD
8166static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8167{
8168 unsigned int gpiostate, gpiomask, gpiodir;
8169
8170 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8171 AC_VERB_GET_GPIO_DATA, 0);
8172
8173 if (!muted)
8174 gpiostate |= (1 << pin);
8175 else
8176 gpiostate &= ~(1 << pin);
8177
8178 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8179 AC_VERB_GET_GPIO_MASK, 0);
8180 gpiomask |= (1 << pin);
8181
8182 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8183 AC_VERB_GET_GPIO_DIRECTION, 0);
8184 gpiodir |= (1 << pin);
8185
8186
8187 snd_hda_codec_write(codec, codec->afg, 0,
8188 AC_VERB_SET_GPIO_MASK, gpiomask);
8189 snd_hda_codec_write(codec, codec->afg, 0,
8190 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8191
8192 msleep(1);
8193
8194 snd_hda_codec_write(codec, codec->afg, 0,
8195 AC_VERB_SET_GPIO_DATA, gpiostate);
8196}
8197
7debbe51
TI
8198/* set up GPIO at initialization */
8199static void alc885_macpro_init_hook(struct hda_codec *codec)
8200{
8201 alc882_gpio_mute(codec, 0, 0);
8202 alc882_gpio_mute(codec, 1, 0);
8203}
8204
8205/* set up GPIO and update auto-muting at initialization */
8206static void alc885_imac24_init_hook(struct hda_codec *codec)
8207{
8208 alc885_macpro_init_hook(codec);
4f5d1706 8209 alc_automute_amp(codec);
7debbe51
TI
8210}
8211
df694daa
KY
8212/*
8213 * generic initialization of ADC, input mixers and output mixers
8214 */
4953550a 8215static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8216 /*
8217 * Unmute ADC0-2 and set the default input to mic-in
8218 */
4953550a
TI
8219 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8222 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8223
4953550a
TI
8224 /*
8225 * Set up output mixers (0x0c - 0x0f)
8226 */
8227 /* set vol=0 to output mixers */
8228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8231 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8232 /* set up input amps for analog loopback */
8233 /* Amp Indices: DAC = 0, mixer = 1 */
8234 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8235 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8236 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8237 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8238 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8239 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8240 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8242 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8243 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8244
4953550a
TI
8245 /* FIXME: use matrix-type input source selection */
8246 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8247 /* Input mixer2 */
88102f3f 8248 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8249 /* Input mixer3 */
88102f3f 8250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8251 { }
9c7f852e
TI
8252};
8253
eb4c41d3
TS
8254/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8255static struct hda_verb alc889A_mb31_ch2_init[] = {
8256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8257 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8258 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8259 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8260 { } /* end */
8261};
8262
8263/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8264static struct hda_verb alc889A_mb31_ch4_init[] = {
8265 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8266 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8267 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8268 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8269 { } /* end */
8270};
8271
8272/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8273static struct hda_verb alc889A_mb31_ch5_init[] = {
8274 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8275 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8276 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8277 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8278 { } /* end */
8279};
8280
8281/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8282static struct hda_verb alc889A_mb31_ch6_init[] = {
8283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8284 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8287 { } /* end */
8288};
8289
8290static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8291 { 2, alc889A_mb31_ch2_init },
8292 { 4, alc889A_mb31_ch4_init },
8293 { 5, alc889A_mb31_ch5_init },
8294 { 6, alc889A_mb31_ch6_init },
8295};
8296
b373bdeb
AN
8297static struct hda_verb alc883_medion_eapd_verbs[] = {
8298 /* eanable EAPD on medion laptop */
8299 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8300 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8301 { }
8302};
8303
4953550a 8304#define alc883_base_mixer alc882_base_mixer
834be88d 8305
a8848bd6
AS
8306static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8311 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8312 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8319 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8320 { } /* end */
8321};
8322
0c4cc443 8323static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8325 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8328 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8329 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8331 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8332 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8333 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8334 { } /* end */
8335};
8336
fb97dc67
J
8337static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8338 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8339 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8340 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8341 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8343 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8345 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8346 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8347 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8348 { } /* end */
8349};
8350
9c7f852e
TI
8351static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8352 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8353 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8354 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8355 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8356 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8360 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8362 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8363 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8365 { } /* end */
8366};
df694daa 8367
9c7f852e
TI
8368static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8371 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8372 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8373 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8374 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8375 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8376 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8377 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8388 { } /* end */
8389};
8390
17bba1b7
J
8391static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8392 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8393 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8394 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8395 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8396 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8397 HDA_OUTPUT),
8398 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8399 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8400 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8404 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8405 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8407 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8408 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8409 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8410 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8412 { } /* end */
8413};
8414
87a8c370
JK
8415static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8417 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8418 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8419 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8420 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8421 HDA_OUTPUT),
8422 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8423 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8424 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8425 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8426 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8431 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8433 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8434 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8436 { } /* end */
8437};
8438
d1d985f0 8439static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8440 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8441 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8442 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8443 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8444 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8445 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8446 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8447 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8448 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8454 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8457 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8459 { } /* end */
8460};
8461
c259249f 8462static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8463 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8464 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8465 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8466 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8468 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8471 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8473 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8474 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8475 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8476 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8478 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8480 { } /* end */
f12ab1e0 8481};
ccc656ce 8482
c259249f 8483static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8486 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8487 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8488 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8489 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8491 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8493 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8494 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8495 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8496 { } /* end */
f12ab1e0 8497};
ccc656ce 8498
b99dba34
TI
8499static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8500 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8501 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8502 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8503 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8504 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8505 { } /* end */
8506};
8507
bc9f98a9
KY
8508static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8509 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8510 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8511 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8512 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8516 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8517 { } /* end */
f12ab1e0 8518};
bc9f98a9 8519
272a527c
KY
8520static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8521 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8522 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8523 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8524 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8525 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8528 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8529 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8530 { } /* end */
8531};
8532
8533static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8534 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8535 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8536 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8541 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8542 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8543 { } /* end */
ea1fb29a 8544};
272a527c 8545
2880a867 8546static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8547 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8548 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8555 { } /* end */
d1a991a6 8556};
2880a867 8557
d2fd4b09
TV
8558static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8559 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8560 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8561 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8562 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8566 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8568 { } /* end */
8569};
8570
e2757d5e
KY
8571static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8572 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8573 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8574 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8575 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8576 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8577 0x0d, 1, 0x0, HDA_OUTPUT),
8578 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8579 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8580 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8581 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8582 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8583 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8584 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8585 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8586 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8588 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8591 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8592 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8593 { } /* end */
8594};
8595
eb4c41d3
TS
8596static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8597 /* Output mixers */
8598 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8599 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8600 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8601 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8602 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8603 HDA_OUTPUT),
8604 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8605 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8607 /* Output switches */
8608 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8609 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8610 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8611 /* Boost mixers */
8612 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8613 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8614 /* Input mixers */
8615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8617 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8618 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8619 { } /* end */
8620};
8621
3e1647c5
GG
8622static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8623 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8624 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8629 { } /* end */
8630};
8631
e2757d5e
KY
8632static struct hda_bind_ctls alc883_bind_cap_vol = {
8633 .ops = &snd_hda_bind_vol,
8634 .values = {
8635 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8636 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8637 0
8638 },
8639};
8640
8641static struct hda_bind_ctls alc883_bind_cap_switch = {
8642 .ops = &snd_hda_bind_sw,
8643 .values = {
8644 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8645 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8646 0
8647 },
8648};
8649
8650static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8651 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8652 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8657 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8659 { } /* end */
8660};
df694daa 8661
4953550a
TI
8662static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8663 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8664 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8665 {
8666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8667 /* .name = "Capture Source", */
8668 .name = "Input Source",
8669 .count = 1,
8670 .info = alc_mux_enum_info,
8671 .get = alc_mux_enum_get,
8672 .put = alc_mux_enum_put,
8673 },
8674 { } /* end */
8675};
9c7f852e 8676
4953550a
TI
8677static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8678 {
8679 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8680 .name = "Channel Mode",
8681 .info = alc_ch_mode_info,
8682 .get = alc_ch_mode_get,
8683 .put = alc_ch_mode_put,
8684 },
8685 { } /* end */
9c7f852e
TI
8686};
8687
a8848bd6 8688/* toggle speaker-output according to the hp-jack state */
4f5d1706 8689static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8690{
a9fd4f3f 8691 struct alc_spec *spec = codec->spec;
a8848bd6 8692
a9fd4f3f
TI
8693 spec->autocfg.hp_pins[0] = 0x15;
8694 spec->autocfg.speaker_pins[0] = 0x14;
8695 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8696}
8697
8698/* auto-toggle front mic */
8699/*
8700static void alc883_mitac_mic_automute(struct hda_codec *codec)
8701{
864f92be 8702 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8703
a8848bd6
AS
8704 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8705}
8706*/
8707
a8848bd6
AS
8708static struct hda_verb alc883_mitac_verbs[] = {
8709 /* HP */
8710 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8712 /* Subwoofer */
8713 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8714 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8715
8716 /* enable unsolicited event */
8717 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8719
8720 { } /* end */
8721};
8722
a65cc60f 8723static struct hda_verb alc883_clevo_m540r_verbs[] = {
8724 /* HP */
8725 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8727 /* Int speaker */
8728 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8729
8730 /* enable unsolicited event */
8731 /*
8732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8734 */
8735
8736 { } /* end */
8737};
8738
0c4cc443 8739static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8740 /* HP */
8741 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8743 /* Int speaker */
8744 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8745 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8746
8747 /* enable unsolicited event */
8748 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8749 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8750
8751 { } /* end */
8752};
8753
fb97dc67
J
8754static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8755 /* HP */
8756 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8758 /* Subwoofer */
8759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8760 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8761
8762 /* enable unsolicited event */
8763 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8764
8765 { } /* end */
8766};
8767
c259249f 8768static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8771
8772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8773 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8774
64a8be74
DH
8775/* Connect Line-Out side jack (SPDIF) to Side */
8776 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8777 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8778 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8779/* Connect Mic jack to CLFE */
8780 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8781 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8782 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8783/* Connect Line-in jack to Surround */
8784 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8785 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8786 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8787/* Connect HP out jack to Front */
8788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8790 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
8791
8792 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
8793
8794 { } /* end */
8795};
8796
bc9f98a9
KY
8797static struct hda_verb alc883_lenovo_101e_verbs[] = {
8798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8800 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8801 { } /* end */
8802};
8803
272a527c
KY
8804static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8805 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8807 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8809 { } /* end */
8810};
8811
8812static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8816 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8817 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8818 { } /* end */
8819};
8820
189609ae
KY
8821static struct hda_verb alc883_haier_w66_verbs[] = {
8822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8824
8825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8826
8827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8828 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8829 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8830 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8831 { } /* end */
8832};
8833
e2757d5e
KY
8834static struct hda_verb alc888_lenovo_sky_verbs[] = {
8835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8839 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8840 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8841 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8842 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8843 { } /* end */
8844};
8845
8718b700
HRK
8846static struct hda_verb alc888_6st_dell_verbs[] = {
8847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8848 { }
8849};
8850
3e1647c5
GG
8851static struct hda_verb alc883_vaiott_verbs[] = {
8852 /* HP */
8853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8855
8856 /* enable unsolicited event */
8857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8858
8859 { } /* end */
8860};
8861
4f5d1706 8862static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 8863{
a9fd4f3f 8864 struct alc_spec *spec = codec->spec;
8718b700 8865
a9fd4f3f
TI
8866 spec->autocfg.hp_pins[0] = 0x1b;
8867 spec->autocfg.speaker_pins[0] = 0x14;
8868 spec->autocfg.speaker_pins[1] = 0x16;
8869 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
8870}
8871
4723c022 8872static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8873 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8874 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8875 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8876 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8877 { } /* end */
5795b9e6
CM
8878};
8879
3ea0d7cf
HRK
8880/*
8881 * 2ch mode
8882 */
4723c022 8883static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8884 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8885 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8886 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8887 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8888 { } /* end */
8341de60
CM
8889};
8890
3ea0d7cf
HRK
8891/*
8892 * 4ch mode
8893 */
8894static struct hda_verb alc888_3st_hp_4ch_init[] = {
8895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8898 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8899 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8900 { } /* end */
8901};
8902
8903/*
8904 * 6ch mode
8905 */
4723c022 8906static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8910 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8911 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8912 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8913 { } /* end */
8341de60
CM
8914};
8915
3ea0d7cf 8916static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8917 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8918 { 4, alc888_3st_hp_4ch_init },
4723c022 8919 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8920};
8921
272a527c
KY
8922/* toggle front-jack and RCA according to the hp-jack state */
8923static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8924{
864f92be 8925 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 8926
47fd830a
TI
8927 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8928 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8929 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8930 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8931}
8932
8933/* toggle RCA according to the front-jack state */
8934static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8935{
864f92be 8936 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 8937
47fd830a
TI
8938 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8939 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8940}
47fd830a 8941
272a527c
KY
8942static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8943 unsigned int res)
8944{
8945 if ((res >> 26) == ALC880_HP_EVENT)
8946 alc888_lenovo_ms7195_front_automute(codec);
8947 if ((res >> 26) == ALC880_FRONT_EVENT)
8948 alc888_lenovo_ms7195_rca_automute(codec);
8949}
8950
8951static struct hda_verb alc883_medion_md2_verbs[] = {
8952 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8954
8955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8956
8957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8958 { } /* end */
8959};
8960
8961/* toggle speaker-output according to the hp-jack state */
4f5d1706 8962static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 8963{
a9fd4f3f 8964 struct alc_spec *spec = codec->spec;
272a527c 8965
a9fd4f3f
TI
8966 spec->autocfg.hp_pins[0] = 0x14;
8967 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
8968}
8969
ccc656ce 8970/* toggle speaker-output according to the hp-jack state */
c259249f
SA
8971#define alc883_targa_init_hook alc882_targa_init_hook
8972#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 8973
0c4cc443
HRK
8974static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8975{
8976 unsigned int present;
8977
d56757ab 8978 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
8979 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8980 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8981}
8982
4f5d1706 8983static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 8984{
a9fd4f3f
TI
8985 struct alc_spec *spec = codec->spec;
8986
8987 spec->autocfg.hp_pins[0] = 0x15;
8988 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
8989}
8990
8991static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8992{
a9fd4f3f 8993 alc_automute_amp(codec);
0c4cc443
HRK
8994 alc883_clevo_m720_mic_automute(codec);
8995}
8996
8997static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8998 unsigned int res)
8999{
0c4cc443 9000 switch (res >> 26) {
0c4cc443
HRK
9001 case ALC880_MIC_EVENT:
9002 alc883_clevo_m720_mic_automute(codec);
9003 break;
a9fd4f3f
TI
9004 default:
9005 alc_automute_amp_unsol_event(codec, res);
9006 break;
0c4cc443 9007 }
368c7a95
J
9008}
9009
fb97dc67 9010/* toggle speaker-output according to the hp-jack state */
4f5d1706 9011static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9012{
a9fd4f3f 9013 struct alc_spec *spec = codec->spec;
fb97dc67 9014
a9fd4f3f
TI
9015 spec->autocfg.hp_pins[0] = 0x14;
9016 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9017}
9018
4f5d1706 9019static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9020{
a9fd4f3f 9021 struct alc_spec *spec = codec->spec;
189609ae 9022
a9fd4f3f
TI
9023 spec->autocfg.hp_pins[0] = 0x1b;
9024 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9025}
9026
bc9f98a9
KY
9027static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9028{
864f92be 9029 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9030
47fd830a
TI
9031 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9032 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9033}
9034
9035static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9036{
864f92be 9037 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9038
47fd830a
TI
9039 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9040 HDA_AMP_MUTE, bits);
9041 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9042 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9043}
9044
9045static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9046 unsigned int res)
9047{
9048 if ((res >> 26) == ALC880_HP_EVENT)
9049 alc883_lenovo_101e_all_automute(codec);
9050 if ((res >> 26) == ALC880_FRONT_EVENT)
9051 alc883_lenovo_101e_ispeaker_automute(codec);
9052}
9053
676a9b53 9054/* toggle speaker-output according to the hp-jack state */
4f5d1706 9055static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9056{
a9fd4f3f 9057 struct alc_spec *spec = codec->spec;
676a9b53 9058
a9fd4f3f
TI
9059 spec->autocfg.hp_pins[0] = 0x14;
9060 spec->autocfg.speaker_pins[0] = 0x15;
9061 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9062}
9063
d1a991a6
KY
9064static struct hda_verb alc883_acer_eapd_verbs[] = {
9065 /* HP Pin: output 0 (0x0c) */
9066 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9067 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9068 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9069 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9070 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9072 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9073 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9074 /* eanable EAPD on medion laptop */
9075 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9076 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9077 /* enable unsolicited event */
9078 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9079 { }
9080};
9081
fc86f954
DK
9082static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9084 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9085 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9086 { } /* end */
9087};
9088
4f5d1706 9089static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9090{
a9fd4f3f 9091 struct alc_spec *spec = codec->spec;
5795b9e6 9092
a9fd4f3f
TI
9093 spec->autocfg.hp_pins[0] = 0x1b;
9094 spec->autocfg.speaker_pins[0] = 0x14;
9095 spec->autocfg.speaker_pins[1] = 0x15;
9096 spec->autocfg.speaker_pins[2] = 0x16;
9097 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9098}
9099
4f5d1706 9100static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9101{
a9fd4f3f 9102 struct alc_spec *spec = codec->spec;
e2757d5e 9103
a9fd4f3f
TI
9104 spec->autocfg.hp_pins[0] = 0x1b;
9105 spec->autocfg.speaker_pins[0] = 0x14;
9106 spec->autocfg.speaker_pins[1] = 0x15;
9107 spec->autocfg.speaker_pins[2] = 0x16;
9108 spec->autocfg.speaker_pins[3] = 0x17;
9109 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9110}
9111
4f5d1706 9112static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9113{
9114 struct alc_spec *spec = codec->spec;
9115
9116 spec->autocfg.hp_pins[0] = 0x15;
9117 spec->autocfg.speaker_pins[0] = 0x14;
9118 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9119}
9120
e2757d5e
KY
9121static struct hda_verb alc888_asus_m90v_verbs[] = {
9122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9125 /* enable unsolicited event */
9126 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9127 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9128 { } /* end */
9129};
9130
4f5d1706 9131static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9132{
a9fd4f3f 9133 struct alc_spec *spec = codec->spec;
e2757d5e 9134
a9fd4f3f
TI
9135 spec->autocfg.hp_pins[0] = 0x1b;
9136 spec->autocfg.speaker_pins[0] = 0x14;
9137 spec->autocfg.speaker_pins[1] = 0x15;
9138 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9139 spec->ext_mic.pin = 0x18;
9140 spec->int_mic.pin = 0x19;
9141 spec->ext_mic.mux_idx = 0;
9142 spec->int_mic.mux_idx = 1;
9143 spec->auto_mic = 1;
e2757d5e
KY
9144}
9145
9146static struct hda_verb alc888_asus_eee1601_verbs[] = {
9147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9149 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9150 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9152 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9153 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9154 /* enable unsolicited event */
9155 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9156 { } /* end */
9157};
9158
e2757d5e
KY
9159static void alc883_eee1601_inithook(struct hda_codec *codec)
9160{
a9fd4f3f
TI
9161 struct alc_spec *spec = codec->spec;
9162
9163 spec->autocfg.hp_pins[0] = 0x14;
9164 spec->autocfg.speaker_pins[0] = 0x1b;
9165 alc_automute_pin(codec);
e2757d5e
KY
9166}
9167
eb4c41d3
TS
9168static struct hda_verb alc889A_mb31_verbs[] = {
9169 /* Init rear pin (used as headphone output) */
9170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9171 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9172 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9173 /* Init line pin (used as output in 4ch and 6ch mode) */
9174 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9175 /* Init line 2 pin (used as headphone out by default) */
9176 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9177 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9178 { } /* end */
9179};
9180
9181/* Mute speakers according to the headphone jack state */
9182static void alc889A_mb31_automute(struct hda_codec *codec)
9183{
9184 unsigned int present;
9185
9186 /* Mute only in 2ch or 4ch mode */
9187 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9188 == 0x00) {
864f92be 9189 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9191 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9192 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9193 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9194 }
9195}
9196
9197static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9198{
9199 if ((res >> 26) == ALC880_HP_EVENT)
9200 alc889A_mb31_automute(codec);
9201}
9202
4953550a 9203
cb53c626 9204#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9205#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9206#endif
9207
def319f9 9208/* pcm configuration: identical with ALC880 */
4953550a
TI
9209#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9210#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9211#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9212#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9213
9214static hda_nid_t alc883_slave_dig_outs[] = {
9215 ALC1200_DIGOUT_NID, 0,
9216};
9217
9218static hda_nid_t alc1200_slave_dig_outs[] = {
9219 ALC883_DIGOUT_NID, 0,
9220};
9c7f852e
TI
9221
9222/*
9223 * configuration and preset
9224 */
4953550a
TI
9225static const char *alc882_models[ALC882_MODEL_LAST] = {
9226 [ALC882_3ST_DIG] = "3stack-dig",
9227 [ALC882_6ST_DIG] = "6stack-dig",
9228 [ALC882_ARIMA] = "arima",
9229 [ALC882_W2JC] = "w2jc",
9230 [ALC882_TARGA] = "targa",
9231 [ALC882_ASUS_A7J] = "asus-a7j",
9232 [ALC882_ASUS_A7M] = "asus-a7m",
9233 [ALC885_MACPRO] = "macpro",
9234 [ALC885_MB5] = "mb5",
e458b1fa 9235 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9236 [ALC885_MBA21] = "mba21",
4953550a
TI
9237 [ALC885_MBP3] = "mbp3",
9238 [ALC885_IMAC24] = "imac24",
4b7e1803 9239 [ALC885_IMAC91] = "imac91",
4953550a 9240 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9241 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9242 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9243 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9244 [ALC883_TARGA_DIG] = "targa-dig",
9245 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9246 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9247 [ALC883_ACER] = "acer",
2880a867 9248 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9249 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9250 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9251 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9252 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9253 [ALC883_MEDION] = "medion",
272a527c 9254 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 9255 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9256 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9257 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9258 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9259 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9260 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9261 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9262 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9263 [ALC883_MITAC] = "mitac",
a65cc60f 9264 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9265 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9266 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9267 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9268 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9269 [ALC889A_INTEL] = "intel-alc889a",
9270 [ALC889_INTEL] = "intel-x58",
3ab90935 9271 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9272 [ALC889A_MB31] = "mb31",
3e1647c5 9273 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9274 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9275};
9276
4953550a
TI
9277static struct snd_pci_quirk alc882_cfg_tbl[] = {
9278 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9279
ac3e3741 9280 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9281 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9282 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9283 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9284 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9285 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9286 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9287 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9288 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9289 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9290 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9291 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9292 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9293 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9294 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9295 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9296 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9297 ALC888_ACER_ASPIRE_6530G),
cc374c47 9298 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9299 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9300 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9301 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9302 /* default Acer -- disabled as it causes more problems.
9303 * model=auto should work fine now
9304 */
9305 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9306
5795b9e6 9307 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9308
febe3375 9309 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9310 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9311 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9312 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9313 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9314 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9315
9316 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9317 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9318 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9319 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9320 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9321 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9322 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9323 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9324 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9325 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9326 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9327
9328 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9329 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9330 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9331 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9332 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9333 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9334 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9335 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9336 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9337
6f3bf657 9338 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9339 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9340 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9341 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9342 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9343 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9344 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9345 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9346 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9347 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9348 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9349 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9350 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9351 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9352 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9353 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9354 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9355 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9356 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9357 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9358 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9359 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9360 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9361 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9362 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9363 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9364 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9365 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9366 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9367 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9368 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9369
ac3e3741 9370 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
9371 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9372 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9373 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9374 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9375 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9376 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9377 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9378 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9379 ALC883_FUJITSU_PI2515),
bfb53037 9380 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9381 ALC888_FUJITSU_XA3530),
272a527c 9382 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9383 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9384 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9385 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9386 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9387 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9388 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9389 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9390 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9391
17bba1b7
J
9392 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9393 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9394 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9395 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9396 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9397 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9398 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9399
4953550a 9400 {}
f3cd3f5d
WF
9401};
9402
4953550a
TI
9403/* codec SSID table for Intel Mac */
9404static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9405 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9406 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9407 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9408 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9409 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9410 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9411 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9412 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9413 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9414 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9415 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9416 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
46ef6ec9
DC
9417 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9418 * so apparently no perfect solution yet
4953550a
TI
9419 */
9420 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9421 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9422 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9423 {} /* terminator */
b25c9da1
WF
9424};
9425
4953550a
TI
9426static struct alc_config_preset alc882_presets[] = {
9427 [ALC882_3ST_DIG] = {
9428 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9429 .init_verbs = { alc882_base_init_verbs,
9430 alc882_adc1_init_verbs },
4953550a
TI
9431 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9432 .dac_nids = alc882_dac_nids,
9433 .dig_out_nid = ALC882_DIGOUT_NID,
9434 .dig_in_nid = ALC882_DIGIN_NID,
9435 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9436 .channel_mode = alc882_ch_modes,
9437 .need_dac_fix = 1,
9438 .input_mux = &alc882_capture_source,
9439 },
9440 [ALC882_6ST_DIG] = {
9441 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9442 .init_verbs = { alc882_base_init_verbs,
9443 alc882_adc1_init_verbs },
4953550a
TI
9444 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9445 .dac_nids = alc882_dac_nids,
9446 .dig_out_nid = ALC882_DIGOUT_NID,
9447 .dig_in_nid = ALC882_DIGIN_NID,
9448 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9449 .channel_mode = alc882_sixstack_modes,
9450 .input_mux = &alc882_capture_source,
9451 },
9452 [ALC882_ARIMA] = {
9453 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9454 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9455 alc882_eapd_verbs },
4953550a
TI
9456 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9457 .dac_nids = alc882_dac_nids,
9458 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9459 .channel_mode = alc882_sixstack_modes,
9460 .input_mux = &alc882_capture_source,
9461 },
9462 [ALC882_W2JC] = {
9463 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9464 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9465 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9466 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9467 .dac_nids = alc882_dac_nids,
9468 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9469 .channel_mode = alc880_threestack_modes,
9470 .need_dac_fix = 1,
9471 .input_mux = &alc882_capture_source,
9472 .dig_out_nid = ALC882_DIGOUT_NID,
9473 },
76e6f5a9
RH
9474 [ALC885_MBA21] = {
9475 .mixers = { alc885_mba21_mixer },
9476 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9477 .num_dacs = 2,
9478 .dac_nids = alc882_dac_nids,
9479 .channel_mode = alc885_mba21_ch_modes,
9480 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9481 .input_mux = &alc882_capture_source,
9482 .unsol_event = alc_automute_amp_unsol_event,
9483 .setup = alc885_mba21_setup,
9484 .init_hook = alc_automute_amp,
9485 },
4953550a
TI
9486 [ALC885_MBP3] = {
9487 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9488 .init_verbs = { alc885_mbp3_init_verbs,
9489 alc880_gpio1_init_verbs },
be0ae923 9490 .num_dacs = 2,
4953550a 9491 .dac_nids = alc882_dac_nids,
be0ae923
TI
9492 .hp_nid = 0x04,
9493 .channel_mode = alc885_mbp_4ch_modes,
9494 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9495 .input_mux = &alc882_capture_source,
9496 .dig_out_nid = ALC882_DIGOUT_NID,
9497 .dig_in_nid = ALC882_DIGIN_NID,
9498 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9499 .setup = alc885_mbp3_setup,
9500 .init_hook = alc_automute_amp,
4953550a
TI
9501 },
9502 [ALC885_MB5] = {
9503 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9504 .init_verbs = { alc885_mb5_init_verbs,
9505 alc880_gpio1_init_verbs },
9506 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9507 .dac_nids = alc882_dac_nids,
9508 .channel_mode = alc885_mb5_6ch_modes,
9509 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9510 .input_mux = &mb5_capture_source,
9511 .dig_out_nid = ALC882_DIGOUT_NID,
9512 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9513 .unsol_event = alc_automute_amp_unsol_event,
9514 .setup = alc885_mb5_setup,
9515 .init_hook = alc_automute_amp,
4953550a 9516 },
e458b1fa
LY
9517 [ALC885_MACMINI3] = {
9518 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9519 .init_verbs = { alc885_macmini3_init_verbs,
9520 alc880_gpio1_init_verbs },
9521 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9522 .dac_nids = alc882_dac_nids,
9523 .channel_mode = alc885_macmini3_6ch_modes,
9524 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9525 .input_mux = &macmini3_capture_source,
9526 .dig_out_nid = ALC882_DIGOUT_NID,
9527 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9528 .unsol_event = alc_automute_amp_unsol_event,
9529 .setup = alc885_macmini3_setup,
9530 .init_hook = alc_automute_amp,
e458b1fa 9531 },
4953550a
TI
9532 [ALC885_MACPRO] = {
9533 .mixers = { alc882_macpro_mixer },
9534 .init_verbs = { alc882_macpro_init_verbs },
9535 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9536 .dac_nids = alc882_dac_nids,
9537 .dig_out_nid = ALC882_DIGOUT_NID,
9538 .dig_in_nid = ALC882_DIGIN_NID,
9539 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9540 .channel_mode = alc882_ch_modes,
9541 .input_mux = &alc882_capture_source,
9542 .init_hook = alc885_macpro_init_hook,
9543 },
9544 [ALC885_IMAC24] = {
9545 .mixers = { alc885_imac24_mixer },
9546 .init_verbs = { alc885_imac24_init_verbs },
9547 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9548 .dac_nids = alc882_dac_nids,
9549 .dig_out_nid = ALC882_DIGOUT_NID,
9550 .dig_in_nid = ALC882_DIGIN_NID,
9551 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9552 .channel_mode = alc882_ch_modes,
9553 .input_mux = &alc882_capture_source,
9554 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9555 .setup = alc885_imac24_setup,
4953550a
TI
9556 .init_hook = alc885_imac24_init_hook,
9557 },
4b7e1803
JM
9558 [ALC885_IMAC91] = {
9559 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
9560 .init_verbs = { alc885_imac91_init_verbs,
9561 alc880_gpio1_init_verbs },
9562 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9563 .dac_nids = alc882_dac_nids,
9564 .channel_mode = alc885_mbp_4ch_modes,
9565 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9566 .input_mux = &alc882_capture_source,
9567 .dig_out_nid = ALC882_DIGOUT_NID,
9568 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9569 .unsol_event = alc_automute_amp_unsol_event,
9570 .setup = alc885_imac91_setup,
9571 .init_hook = alc_automute_amp,
4b7e1803 9572 },
4953550a
TI
9573 [ALC882_TARGA] = {
9574 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9575 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9576 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9577 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9578 .dac_nids = alc882_dac_nids,
9579 .dig_out_nid = ALC882_DIGOUT_NID,
9580 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9581 .adc_nids = alc882_adc_nids,
9582 .capsrc_nids = alc882_capsrc_nids,
9583 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9584 .channel_mode = alc882_3ST_6ch_modes,
9585 .need_dac_fix = 1,
9586 .input_mux = &alc882_capture_source,
9587 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9588 .setup = alc882_targa_setup,
9589 .init_hook = alc882_targa_automute,
4953550a
TI
9590 },
9591 [ALC882_ASUS_A7J] = {
9592 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9593 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9594 alc882_asus_a7j_verbs},
4953550a
TI
9595 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9596 .dac_nids = alc882_dac_nids,
9597 .dig_out_nid = ALC882_DIGOUT_NID,
9598 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9599 .adc_nids = alc882_adc_nids,
9600 .capsrc_nids = alc882_capsrc_nids,
9601 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9602 .channel_mode = alc882_3ST_6ch_modes,
9603 .need_dac_fix = 1,
9604 .input_mux = &alc882_capture_source,
9605 },
9606 [ALC882_ASUS_A7M] = {
9607 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9608 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9609 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9610 alc882_asus_a7m_verbs },
9611 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9612 .dac_nids = alc882_dac_nids,
9613 .dig_out_nid = ALC882_DIGOUT_NID,
9614 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9615 .channel_mode = alc880_threestack_modes,
9616 .need_dac_fix = 1,
9617 .input_mux = &alc882_capture_source,
9618 },
9c7f852e
TI
9619 [ALC883_3ST_2ch_DIG] = {
9620 .mixers = { alc883_3ST_2ch_mixer },
9621 .init_verbs = { alc883_init_verbs },
9622 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9623 .dac_nids = alc883_dac_nids,
9624 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9625 .dig_in_nid = ALC883_DIGIN_NID,
9626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9627 .channel_mode = alc883_3ST_2ch_modes,
9628 .input_mux = &alc883_capture_source,
9629 },
9630 [ALC883_3ST_6ch_DIG] = {
9631 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9632 .init_verbs = { alc883_init_verbs },
9633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9634 .dac_nids = alc883_dac_nids,
9635 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9636 .dig_in_nid = ALC883_DIGIN_NID,
9637 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9638 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9639 .need_dac_fix = 1,
9c7f852e 9640 .input_mux = &alc883_capture_source,
f12ab1e0 9641 },
9c7f852e
TI
9642 [ALC883_3ST_6ch] = {
9643 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9644 .init_verbs = { alc883_init_verbs },
9645 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9646 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9647 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9648 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9649 .need_dac_fix = 1,
9c7f852e 9650 .input_mux = &alc883_capture_source,
f12ab1e0 9651 },
17bba1b7
J
9652 [ALC883_3ST_6ch_INTEL] = {
9653 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9654 .init_verbs = { alc883_init_verbs },
9655 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9656 .dac_nids = alc883_dac_nids,
9657 .dig_out_nid = ALC883_DIGOUT_NID,
9658 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9659 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9661 .channel_mode = alc883_3ST_6ch_intel_modes,
9662 .need_dac_fix = 1,
9663 .input_mux = &alc883_3stack_6ch_intel,
9664 },
87a8c370
JK
9665 [ALC889A_INTEL] = {
9666 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9667 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9668 alc_hp15_unsol_verbs },
87a8c370
JK
9669 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9670 .dac_nids = alc883_dac_nids,
9671 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9672 .adc_nids = alc889_adc_nids,
9673 .dig_out_nid = ALC883_DIGOUT_NID,
9674 .dig_in_nid = ALC883_DIGIN_NID,
9675 .slave_dig_outs = alc883_slave_dig_outs,
9676 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9677 .channel_mode = alc889_8ch_intel_modes,
9678 .capsrc_nids = alc889_capsrc_nids,
9679 .input_mux = &alc889_capture_source,
4f5d1706
TI
9680 .setup = alc889_automute_setup,
9681 .init_hook = alc_automute_amp,
6732bd0d 9682 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9683 .need_dac_fix = 1,
9684 },
9685 [ALC889_INTEL] = {
9686 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9687 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9688 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9689 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9690 .dac_nids = alc883_dac_nids,
9691 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9692 .adc_nids = alc889_adc_nids,
9693 .dig_out_nid = ALC883_DIGOUT_NID,
9694 .dig_in_nid = ALC883_DIGIN_NID,
9695 .slave_dig_outs = alc883_slave_dig_outs,
9696 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9697 .channel_mode = alc889_8ch_intel_modes,
9698 .capsrc_nids = alc889_capsrc_nids,
9699 .input_mux = &alc889_capture_source,
4f5d1706 9700 .setup = alc889_automute_setup,
6732bd0d
WF
9701 .init_hook = alc889_intel_init_hook,
9702 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9703 .need_dac_fix = 1,
9704 },
9c7f852e
TI
9705 [ALC883_6ST_DIG] = {
9706 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9707 .init_verbs = { alc883_init_verbs },
9708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9709 .dac_nids = alc883_dac_nids,
9710 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9711 .dig_in_nid = ALC883_DIGIN_NID,
9712 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9713 .channel_mode = alc883_sixstack_modes,
9714 .input_mux = &alc883_capture_source,
9715 },
ccc656ce 9716 [ALC883_TARGA_DIG] = {
c259249f 9717 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9718 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9719 alc883_targa_verbs},
ccc656ce
KY
9720 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9721 .dac_nids = alc883_dac_nids,
9722 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9723 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9724 .channel_mode = alc883_3ST_6ch_modes,
9725 .need_dac_fix = 1,
9726 .input_mux = &alc883_capture_source,
c259249f 9727 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9728 .setup = alc882_targa_setup,
9729 .init_hook = alc882_targa_automute,
ccc656ce
KY
9730 },
9731 [ALC883_TARGA_2ch_DIG] = {
c259249f 9732 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9733 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9734 alc883_targa_verbs},
ccc656ce
KY
9735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9736 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9737 .adc_nids = alc883_adc_nids_alt,
9738 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9739 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9740 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9741 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9742 .channel_mode = alc883_3ST_2ch_modes,
9743 .input_mux = &alc883_capture_source,
c259249f 9744 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9745 .setup = alc882_targa_setup,
9746 .init_hook = alc882_targa_automute,
ccc656ce 9747 },
64a8be74 9748 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9749 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9750 alc883_chmode_mixer },
64a8be74 9751 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9752 alc883_targa_verbs },
64a8be74
DH
9753 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9754 .dac_nids = alc883_dac_nids,
9755 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9756 .adc_nids = alc883_adc_nids_rev,
9757 .capsrc_nids = alc883_capsrc_nids_rev,
9758 .dig_out_nid = ALC883_DIGOUT_NID,
9759 .dig_in_nid = ALC883_DIGIN_NID,
9760 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9761 .channel_mode = alc883_4ST_8ch_modes,
9762 .need_dac_fix = 1,
9763 .input_mux = &alc883_capture_source,
c259249f 9764 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9765 .setup = alc882_targa_setup,
9766 .init_hook = alc882_targa_automute,
64a8be74 9767 },
bab282b9 9768 [ALC883_ACER] = {
676a9b53 9769 .mixers = { alc883_base_mixer },
bab282b9
VA
9770 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9771 * and the headphone jack. Turn this on and rely on the
9772 * standard mute methods whenever the user wants to turn
9773 * these outputs off.
9774 */
9775 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9777 .dac_nids = alc883_dac_nids,
bab282b9
VA
9778 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9779 .channel_mode = alc883_3ST_2ch_modes,
9780 .input_mux = &alc883_capture_source,
9781 },
2880a867 9782 [ALC883_ACER_ASPIRE] = {
676a9b53 9783 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 9784 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
9785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9786 .dac_nids = alc883_dac_nids,
9787 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
9788 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9789 .channel_mode = alc883_3ST_2ch_modes,
9790 .input_mux = &alc883_capture_source,
a9fd4f3f 9791 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9792 .setup = alc883_acer_aspire_setup,
9793 .init_hook = alc_automute_amp,
d1a991a6 9794 },
5b2d1eca 9795 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 9796 .mixers = { alc888_base_mixer,
5b2d1eca
VP
9797 alc883_chmode_mixer },
9798 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9799 alc888_acer_aspire_4930g_verbs },
9800 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9801 .dac_nids = alc883_dac_nids,
9802 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9803 .adc_nids = alc883_adc_nids_rev,
9804 .capsrc_nids = alc883_capsrc_nids_rev,
9805 .dig_out_nid = ALC883_DIGOUT_NID,
9806 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9807 .channel_mode = alc883_3ST_6ch_modes,
9808 .need_dac_fix = 1,
973b8cb0 9809 .const_channel_count = 6,
5b2d1eca 9810 .num_mux_defs =
ef8ef5fb
VP
9811 ARRAY_SIZE(alc888_2_capture_sources),
9812 .input_mux = alc888_2_capture_sources,
d2fd4b09 9813 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9814 .setup = alc888_acer_aspire_4930g_setup,
9815 .init_hook = alc_automute_amp,
d2fd4b09
TV
9816 },
9817 [ALC888_ACER_ASPIRE_6530G] = {
9818 .mixers = { alc888_acer_aspire_6530_mixer },
9819 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9820 alc888_acer_aspire_6530g_verbs },
9821 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9822 .dac_nids = alc883_dac_nids,
9823 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9824 .adc_nids = alc883_adc_nids_rev,
9825 .capsrc_nids = alc883_capsrc_nids_rev,
9826 .dig_out_nid = ALC883_DIGOUT_NID,
9827 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9828 .channel_mode = alc883_3ST_2ch_modes,
9829 .num_mux_defs =
9830 ARRAY_SIZE(alc888_2_capture_sources),
9831 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 9832 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9833 .setup = alc888_acer_aspire_6530g_setup,
9834 .init_hook = alc_automute_amp,
5b2d1eca 9835 },
3b315d70 9836 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 9837 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
9838 alc883_chmode_mixer },
9839 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
9840 alc889_acer_aspire_8930g_verbs,
9841 alc889_eapd_verbs},
3b315d70
HM
9842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9843 .dac_nids = alc883_dac_nids,
018df418
HM
9844 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9845 .adc_nids = alc889_adc_nids,
9846 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
9847 .dig_out_nid = ALC883_DIGOUT_NID,
9848 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9849 .channel_mode = alc883_3ST_6ch_modes,
9850 .need_dac_fix = 1,
9851 .const_channel_count = 6,
9852 .num_mux_defs =
018df418
HM
9853 ARRAY_SIZE(alc889_capture_sources),
9854 .input_mux = alc889_capture_sources,
3b315d70 9855 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9856 .setup = alc889_acer_aspire_8930g_setup,
9857 .init_hook = alc_automute_amp,
f5de24b0 9858#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 9859 .power_hook = alc_power_eapd,
f5de24b0 9860#endif
3b315d70 9861 },
fc86f954
DK
9862 [ALC888_ACER_ASPIRE_7730G] = {
9863 .mixers = { alc883_3ST_6ch_mixer,
9864 alc883_chmode_mixer },
9865 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9866 alc888_acer_aspire_7730G_verbs },
9867 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9868 .dac_nids = alc883_dac_nids,
9869 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9870 .adc_nids = alc883_adc_nids_rev,
9871 .capsrc_nids = alc883_capsrc_nids_rev,
9872 .dig_out_nid = ALC883_DIGOUT_NID,
9873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9874 .channel_mode = alc883_3ST_6ch_modes,
9875 .need_dac_fix = 1,
9876 .const_channel_count = 6,
9877 .input_mux = &alc883_capture_source,
9878 .unsol_event = alc_automute_amp_unsol_event,
9879 .setup = alc888_acer_aspire_6530g_setup,
9880 .init_hook = alc_automute_amp,
9881 },
c07584c8
TD
9882 [ALC883_MEDION] = {
9883 .mixers = { alc883_fivestack_mixer,
9884 alc883_chmode_mixer },
9885 .init_verbs = { alc883_init_verbs,
b373bdeb 9886 alc883_medion_eapd_verbs },
c07584c8
TD
9887 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9888 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9889 .adc_nids = alc883_adc_nids_alt,
9890 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9891 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
9892 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9893 .channel_mode = alc883_sixstack_modes,
9894 .input_mux = &alc883_capture_source,
b373bdeb 9895 },
272a527c
KY
9896 [ALC883_MEDION_MD2] = {
9897 .mixers = { alc883_medion_md2_mixer},
9898 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9899 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9900 .dac_nids = alc883_dac_nids,
9901 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9902 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9903 .channel_mode = alc883_3ST_2ch_modes,
9904 .input_mux = &alc883_capture_source,
a9fd4f3f 9905 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9906 .setup = alc883_medion_md2_setup,
9907 .init_hook = alc_automute_amp,
ea1fb29a 9908 },
b373bdeb 9909 [ALC883_LAPTOP_EAPD] = {
676a9b53 9910 .mixers = { alc883_base_mixer },
b373bdeb
AN
9911 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9912 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9913 .dac_nids = alc883_dac_nids,
b373bdeb
AN
9914 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9915 .channel_mode = alc883_3ST_2ch_modes,
9916 .input_mux = &alc883_capture_source,
9917 },
a65cc60f 9918 [ALC883_CLEVO_M540R] = {
9919 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9920 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9921 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9922 .dac_nids = alc883_dac_nids,
9923 .dig_out_nid = ALC883_DIGOUT_NID,
9924 .dig_in_nid = ALC883_DIGIN_NID,
9925 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9926 .channel_mode = alc883_3ST_6ch_clevo_modes,
9927 .need_dac_fix = 1,
9928 .input_mux = &alc883_capture_source,
9929 /* This machine has the hardware HP auto-muting, thus
9930 * we need no software mute via unsol event
9931 */
9932 },
0c4cc443
HRK
9933 [ALC883_CLEVO_M720] = {
9934 .mixers = { alc883_clevo_m720_mixer },
9935 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
9936 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9937 .dac_nids = alc883_dac_nids,
9938 .dig_out_nid = ALC883_DIGOUT_NID,
9939 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9940 .channel_mode = alc883_3ST_2ch_modes,
9941 .input_mux = &alc883_capture_source,
0c4cc443 9942 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 9943 .setup = alc883_clevo_m720_setup,
a9fd4f3f 9944 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 9945 },
bc9f98a9
KY
9946 [ALC883_LENOVO_101E_2ch] = {
9947 .mixers = { alc883_lenovo_101e_2ch_mixer},
9948 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9949 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9950 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9951 .adc_nids = alc883_adc_nids_alt,
9952 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9953 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
9954 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9955 .channel_mode = alc883_3ST_2ch_modes,
9956 .input_mux = &alc883_lenovo_101e_capture_source,
9957 .unsol_event = alc883_lenovo_101e_unsol_event,
9958 .init_hook = alc883_lenovo_101e_all_automute,
9959 },
272a527c
KY
9960 [ALC883_LENOVO_NB0763] = {
9961 .mixers = { alc883_lenovo_nb0763_mixer },
9962 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9963 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9964 .dac_nids = alc883_dac_nids,
272a527c
KY
9965 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9966 .channel_mode = alc883_3ST_2ch_modes,
9967 .need_dac_fix = 1,
9968 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 9969 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9970 .setup = alc883_medion_md2_setup,
9971 .init_hook = alc_automute_amp,
272a527c
KY
9972 },
9973 [ALC888_LENOVO_MS7195_DIG] = {
9974 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9975 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9976 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9977 .dac_nids = alc883_dac_nids,
9978 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
9979 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9980 .channel_mode = alc883_3ST_6ch_modes,
9981 .need_dac_fix = 1,
9982 .input_mux = &alc883_capture_source,
9983 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9984 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
9985 },
9986 [ALC883_HAIER_W66] = {
c259249f 9987 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
9988 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9989 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9990 .dac_nids = alc883_dac_nids,
9991 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
9992 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9993 .channel_mode = alc883_3ST_2ch_modes,
9994 .input_mux = &alc883_capture_source,
a9fd4f3f 9995 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9996 .setup = alc883_haier_w66_setup,
9997 .init_hook = alc_automute_amp,
eea6419e 9998 },
4723c022 9999 [ALC888_3ST_HP] = {
eea6419e 10000 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10001 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10002 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10003 .dac_nids = alc883_dac_nids,
4723c022
CM
10004 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10005 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10006 .need_dac_fix = 1,
10007 .input_mux = &alc883_capture_source,
a9fd4f3f 10008 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10009 .setup = alc888_3st_hp_setup,
10010 .init_hook = alc_automute_amp,
8341de60 10011 },
5795b9e6 10012 [ALC888_6ST_DELL] = {
f24dbdc6 10013 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10014 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10015 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10016 .dac_nids = alc883_dac_nids,
10017 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10018 .dig_in_nid = ALC883_DIGIN_NID,
10019 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10020 .channel_mode = alc883_sixstack_modes,
10021 .input_mux = &alc883_capture_source,
a9fd4f3f 10022 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10023 .setup = alc888_6st_dell_setup,
10024 .init_hook = alc_automute_amp,
5795b9e6 10025 },
a8848bd6
AS
10026 [ALC883_MITAC] = {
10027 .mixers = { alc883_mitac_mixer },
10028 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10029 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10030 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10031 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10032 .channel_mode = alc883_3ST_2ch_modes,
10033 .input_mux = &alc883_capture_source,
a9fd4f3f 10034 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10035 .setup = alc883_mitac_setup,
10036 .init_hook = alc_automute_amp,
a8848bd6 10037 },
fb97dc67
J
10038 [ALC883_FUJITSU_PI2515] = {
10039 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10040 .init_verbs = { alc883_init_verbs,
10041 alc883_2ch_fujitsu_pi2515_verbs},
10042 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10043 .dac_nids = alc883_dac_nids,
10044 .dig_out_nid = ALC883_DIGOUT_NID,
10045 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10046 .channel_mode = alc883_3ST_2ch_modes,
10047 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10048 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10049 .setup = alc883_2ch_fujitsu_pi2515_setup,
10050 .init_hook = alc_automute_amp,
fb97dc67 10051 },
ef8ef5fb
VP
10052 [ALC888_FUJITSU_XA3530] = {
10053 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10054 .init_verbs = { alc883_init_verbs,
10055 alc888_fujitsu_xa3530_verbs },
10056 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10057 .dac_nids = alc883_dac_nids,
10058 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10059 .adc_nids = alc883_adc_nids_rev,
10060 .capsrc_nids = alc883_capsrc_nids_rev,
10061 .dig_out_nid = ALC883_DIGOUT_NID,
10062 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10063 .channel_mode = alc888_4ST_8ch_intel_modes,
10064 .num_mux_defs =
10065 ARRAY_SIZE(alc888_2_capture_sources),
10066 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10067 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10068 .setup = alc888_fujitsu_xa3530_setup,
10069 .init_hook = alc_automute_amp,
ef8ef5fb 10070 },
e2757d5e
KY
10071 [ALC888_LENOVO_SKY] = {
10072 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10073 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10074 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10075 .dac_nids = alc883_dac_nids,
10076 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10077 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10078 .channel_mode = alc883_sixstack_modes,
10079 .need_dac_fix = 1,
10080 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10081 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10082 .setup = alc888_lenovo_sky_setup,
10083 .init_hook = alc_automute_amp,
e2757d5e
KY
10084 },
10085 [ALC888_ASUS_M90V] = {
10086 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10087 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10088 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10089 .dac_nids = alc883_dac_nids,
10090 .dig_out_nid = ALC883_DIGOUT_NID,
10091 .dig_in_nid = ALC883_DIGIN_NID,
10092 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10093 .channel_mode = alc883_3ST_6ch_modes,
10094 .need_dac_fix = 1,
10095 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10096 .unsol_event = alc_sku_unsol_event,
10097 .setup = alc883_mode2_setup,
10098 .init_hook = alc_inithook,
e2757d5e
KY
10099 },
10100 [ALC888_ASUS_EEE1601] = {
10101 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10102 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10103 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10104 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10105 .dac_nids = alc883_dac_nids,
10106 .dig_out_nid = ALC883_DIGOUT_NID,
10107 .dig_in_nid = ALC883_DIGIN_NID,
10108 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10109 .channel_mode = alc883_3ST_2ch_modes,
10110 .need_dac_fix = 1,
10111 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10112 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10113 .init_hook = alc883_eee1601_inithook,
10114 },
3ab90935
WF
10115 [ALC1200_ASUS_P5Q] = {
10116 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10117 .init_verbs = { alc883_init_verbs },
10118 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10119 .dac_nids = alc883_dac_nids,
10120 .dig_out_nid = ALC1200_DIGOUT_NID,
10121 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10122 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10123 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10124 .channel_mode = alc883_sixstack_modes,
10125 .input_mux = &alc883_capture_source,
10126 },
eb4c41d3
TS
10127 [ALC889A_MB31] = {
10128 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10129 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10130 alc880_gpio1_init_verbs },
10131 .adc_nids = alc883_adc_nids,
10132 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10133 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10134 .dac_nids = alc883_dac_nids,
10135 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10136 .channel_mode = alc889A_mb31_6ch_modes,
10137 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10138 .input_mux = &alc889A_mb31_capture_source,
10139 .dig_out_nid = ALC883_DIGOUT_NID,
10140 .unsol_event = alc889A_mb31_unsol_event,
10141 .init_hook = alc889A_mb31_automute,
10142 },
3e1647c5
GG
10143 [ALC883_SONY_VAIO_TT] = {
10144 .mixers = { alc883_vaiott_mixer },
10145 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10146 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10147 .dac_nids = alc883_dac_nids,
10148 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10149 .channel_mode = alc883_3ST_2ch_modes,
10150 .input_mux = &alc883_capture_source,
10151 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10152 .setup = alc883_vaiott_setup,
10153 .init_hook = alc_automute_amp,
3e1647c5 10154 },
9c7f852e
TI
10155};
10156
10157
4953550a
TI
10158/*
10159 * Pin config fixes
10160 */
10161enum {
10162 PINFIX_ABIT_AW9D_MAX
10163};
10164
10165static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10166 { 0x15, 0x01080104 }, /* side */
10167 { 0x16, 0x01011012 }, /* rear */
10168 { 0x17, 0x01016011 }, /* clfe */
10169 { }
10170};
10171
f8f25ba3
TI
10172static const struct alc_fixup alc882_fixups[] = {
10173 [PINFIX_ABIT_AW9D_MAX] = {
10174 .pins = alc882_abit_aw9d_pinfix
10175 },
4953550a
TI
10176};
10177
f8f25ba3 10178static struct snd_pci_quirk alc882_fixup_tbl[] = {
4953550a
TI
10179 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10180 {}
10181};
10182
9c7f852e
TI
10183/*
10184 * BIOS auto configuration
10185 */
05f5f477
TI
10186static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10187 const struct auto_pin_cfg *cfg)
10188{
10189 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10190}
10191
4953550a 10192static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e
TI
10193 hda_nid_t nid, int pin_type,
10194 int dac_idx)
10195{
10196 /* set as output */
10197 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
10198 int idx;
10199
f6c7e546 10200 alc_set_pin_output(codec, nid, pin_type);
f9700d5a
TI
10201 if (dac_idx >= spec->multiout.num_dacs)
10202 return;
9c7f852e
TI
10203 if (spec->multiout.dac_nids[dac_idx] == 0x25)
10204 idx = 4;
f9700d5a 10205 else
9c7f852e 10206 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
10207 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10208
10209}
10210
4953550a 10211static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10212{
10213 struct alc_spec *spec = codec->spec;
10214 int i;
10215
10216 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10217 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10218 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10219 if (nid)
4953550a 10220 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 10221 i);
9c7f852e
TI
10222 }
10223}
10224
4953550a 10225static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10226{
10227 struct alc_spec *spec = codec->spec;
10228 hda_nid_t pin;
10229
eb06ed8f 10230 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
10231 if (pin) /* connect to front */
10232 /* use dac 0 */
4953550a 10233 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
10234 pin = spec->autocfg.speaker_pins[0];
10235 if (pin)
4953550a 10236 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
10237}
10238
4953550a 10239static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10240{
10241 struct alc_spec *spec = codec->spec;
10242 int i;
10243
10244 for (i = 0; i < AUTO_PIN_LAST; i++) {
10245 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10246 if (!nid)
10247 continue;
0d971c9f 10248 alc_set_input_pin(codec, nid, i);
4953550a
TI
10249 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10250 snd_hda_codec_write(codec, nid, 0,
10251 AC_VERB_SET_AMP_GAIN_MUTE,
10252 AMP_OUT_MUTE);
10253 }
10254}
10255
10256static void alc882_auto_init_input_src(struct hda_codec *codec)
10257{
10258 struct alc_spec *spec = codec->spec;
10259 int c;
10260
10261 for (c = 0; c < spec->num_adc_nids; c++) {
10262 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10263 hda_nid_t nid = spec->capsrc_nids[c];
10264 unsigned int mux_idx;
10265 const struct hda_input_mux *imux;
10266 int conns, mute, idx, item;
10267
10268 conns = snd_hda_get_connections(codec, nid, conn_list,
10269 ARRAY_SIZE(conn_list));
10270 if (conns < 0)
10271 continue;
10272 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10273 imux = &spec->input_mux[mux_idx];
5311114d
TI
10274 if (!imux->num_items && mux_idx > 0)
10275 imux = &spec->input_mux[0];
4953550a
TI
10276 for (idx = 0; idx < conns; idx++) {
10277 /* if the current connection is the selected one,
10278 * unmute it as default - otherwise mute it
10279 */
10280 mute = AMP_IN_MUTE(idx);
10281 for (item = 0; item < imux->num_items; item++) {
10282 if (imux->items[item].index == idx) {
10283 if (spec->cur_mux[c] == item)
10284 mute = AMP_IN_UNMUTE(idx);
10285 break;
10286 }
10287 }
10288 /* check if we have a selector or mixer
10289 * we could check for the widget type instead, but
10290 * just check for Amp-In presence (in case of mixer
10291 * without amp-in there is something wrong, this
10292 * function shouldn't be used or capsrc nid is wrong)
10293 */
10294 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10295 snd_hda_codec_write(codec, nid, 0,
10296 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10297 mute);
10298 else if (mute != AMP_IN_MUTE(idx))
10299 snd_hda_codec_write(codec, nid, 0,
10300 AC_VERB_SET_CONNECT_SEL,
10301 idx);
9c7f852e
TI
10302 }
10303 }
10304}
10305
4953550a
TI
10306/* add mic boosts if needed */
10307static int alc_auto_add_mic_boost(struct hda_codec *codec)
10308{
10309 struct alc_spec *spec = codec->spec;
10310 int err;
10311 hda_nid_t nid;
10312
10313 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10314 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10315 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10316 "Mic Boost",
10317 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10318 if (err < 0)
10319 return err;
10320 }
10321 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10322 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10323 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10324 "Front Mic Boost",
10325 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10326 if (err < 0)
10327 return err;
10328 }
10329 return 0;
10330}
f511b01c 10331
9c7f852e 10332/* almost identical with ALC880 parser... */
4953550a 10333static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10334{
10335 struct alc_spec *spec = codec->spec;
05f5f477
TI
10336 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10337 int i, err;
9c7f852e 10338
05f5f477
TI
10339 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10340 alc882_ignore);
9c7f852e
TI
10341 if (err < 0)
10342 return err;
05f5f477
TI
10343 if (!spec->autocfg.line_outs)
10344 return 0; /* can't find valid BIOS pin config */
776e184e 10345
05f5f477
TI
10346 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10347 if (err < 0)
10348 return err;
10349 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10350 if (err < 0)
10351 return err;
10352 err = alc880_auto_create_extra_out(spec,
10353 spec->autocfg.speaker_pins[0],
10354 "Speaker");
10355 if (err < 0)
10356 return err;
10357 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10358 "Headphone");
10359 if (err < 0)
10360 return err;
10361 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10362 if (err < 0)
10363 return err;
10364
05f5f477
TI
10365 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10366
10367 /* check multiple SPDIF-out (for recent codecs) */
10368 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10369 hda_nid_t dig_nid;
10370 err = snd_hda_get_connections(codec,
10371 spec->autocfg.dig_out_pins[i],
10372 &dig_nid, 1);
10373 if (err < 0)
10374 continue;
10375 if (!i)
10376 spec->multiout.dig_out_nid = dig_nid;
10377 else {
10378 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 10379 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
05f5f477 10380 break;
71121d9f 10381 spec->slave_dig_outs[i - 1] = dig_nid;
05f5f477
TI
10382 }
10383 }
10384 if (spec->autocfg.dig_in_pin)
10385 spec->dig_in_nid = ALC880_DIGIN_NID;
10386
10387 if (spec->kctls.list)
10388 add_mixer(spec, spec->kctls.list);
10389
10390 add_verb(spec, alc883_auto_init_verbs);
4953550a 10391 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10392 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10393 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10394
05f5f477
TI
10395 spec->num_mux_defs = 1;
10396 spec->input_mux = &spec->private_imux[0];
10397
6227cdce 10398 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10399
10400 err = alc_auto_add_mic_boost(codec);
10401 if (err < 0)
10402 return err;
61b9b9b1 10403
776e184e 10404 return 1; /* config found */
9c7f852e
TI
10405}
10406
10407/* additional initialization for auto-configuration model */
4953550a 10408static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10409{
f6c7e546 10410 struct alc_spec *spec = codec->spec;
4953550a
TI
10411 alc882_auto_init_multi_out(codec);
10412 alc882_auto_init_hp_out(codec);
10413 alc882_auto_init_analog_input(codec);
10414 alc882_auto_init_input_src(codec);
f6c7e546 10415 if (spec->unsol_event)
7fb0d78f 10416 alc_inithook(codec);
9c7f852e
TI
10417}
10418
4953550a 10419static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10420{
10421 struct alc_spec *spec;
10422 int err, board_config;
10423
10424 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10425 if (spec == NULL)
10426 return -ENOMEM;
10427
10428 codec->spec = spec;
10429
da00c244
KY
10430 alc_auto_parse_customize_define(codec);
10431
4953550a
TI
10432 switch (codec->vendor_id) {
10433 case 0x10ec0882:
10434 case 0x10ec0885:
10435 break;
10436 default:
10437 /* ALC883 and variants */
10438 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10439 break;
10440 }
2c3bf9ab 10441
4953550a
TI
10442 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10443 alc882_models,
10444 alc882_cfg_tbl);
10445
10446 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10447 board_config = snd_hda_check_board_codec_sid_config(codec,
10448 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10449
10450 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10451 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10452 codec->chip_name);
10453 board_config = ALC882_AUTO;
9c7f852e
TI
10454 }
10455
f8f25ba3 10456 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
4953550a
TI
10457
10458 if (board_config == ALC882_AUTO) {
9c7f852e 10459 /* automatic parse from the BIOS config */
4953550a 10460 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10461 if (err < 0) {
10462 alc_free(codec);
10463 return err;
f12ab1e0 10464 } else if (!err) {
9c7f852e
TI
10465 printk(KERN_INFO
10466 "hda_codec: Cannot set up configuration "
10467 "from BIOS. Using base mode...\n");
4953550a 10468 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10469 }
10470 }
10471
680cd536
KK
10472 err = snd_hda_attach_beep_device(codec, 0x1);
10473 if (err < 0) {
10474 alc_free(codec);
10475 return err;
10476 }
10477
4953550a 10478 if (board_config != ALC882_AUTO)
e9c364c0 10479 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10480
4953550a
TI
10481 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10482 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10483 /* FIXME: setup DAC5 */
10484 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10485 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10486
10487 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10488 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10489
10490 if (codec->vendor_id == 0x10ec0888)
4a79ba34 10491 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
4953550a
TI
10492
10493 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10494 int i, j;
4953550a
TI
10495 spec->num_adc_nids = 0;
10496 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10497 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10498 hda_nid_t cap;
d11f74c6 10499 hda_nid_t items[16];
4953550a
TI
10500 hda_nid_t nid = alc882_adc_nids[i];
10501 unsigned int wcap = get_wcaps(codec, nid);
10502 /* get type */
a22d543a 10503 wcap = get_wcaps_type(wcap);
4953550a
TI
10504 if (wcap != AC_WID_AUD_IN)
10505 continue;
10506 spec->private_adc_nids[spec->num_adc_nids] = nid;
10507 err = snd_hda_get_connections(codec, nid, &cap, 1);
10508 if (err < 0)
10509 continue;
d11f74c6
TI
10510 err = snd_hda_get_connections(codec, cap, items,
10511 ARRAY_SIZE(items));
10512 if (err < 0)
10513 continue;
10514 for (j = 0; j < imux->num_items; j++)
10515 if (imux->items[j].index >= err)
10516 break;
10517 if (j < imux->num_items)
10518 continue;
4953550a
TI
10519 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10520 spec->num_adc_nids++;
61b9b9b1 10521 }
4953550a
TI
10522 spec->adc_nids = spec->private_adc_nids;
10523 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10524 }
10525
b59bdf3b 10526 set_capture_mixer(codec);
da00c244
KY
10527
10528 if (spec->cdefine.enable_pcbeep)
10529 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10530
2134ea4f
TI
10531 spec->vmaster_nid = 0x0c;
10532
9c7f852e 10533 codec->patch_ops = alc_patch_ops;
4953550a
TI
10534 if (board_config == ALC882_AUTO)
10535 spec->init_hook = alc882_auto_init;
cb53c626
TI
10536#ifdef CONFIG_SND_HDA_POWER_SAVE
10537 if (!spec->loopback.amplist)
4953550a 10538 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10539#endif
9c7f852e
TI
10540
10541 return 0;
10542}
10543
4953550a 10544
9c7f852e
TI
10545/*
10546 * ALC262 support
10547 */
10548
10549#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10550#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10551
10552#define alc262_dac_nids alc260_dac_nids
10553#define alc262_adc_nids alc882_adc_nids
10554#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10555#define alc262_capsrc_nids alc882_capsrc_nids
10556#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10557
10558#define alc262_modes alc260_modes
10559#define alc262_capture_source alc882_capture_source
10560
4e555fe5
KY
10561static hda_nid_t alc262_dmic_adc_nids[1] = {
10562 /* ADC0 */
10563 0x09
10564};
10565
10566static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10567
9c7f852e
TI
10568static struct snd_kcontrol_new alc262_base_mixer[] = {
10569 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10570 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10577 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10579 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10580 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10581 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10583 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10584 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10585 { } /* end */
10586};
10587
ce875f07
TI
10588/* update HP, line and mono-out pins according to the master switch */
10589static void alc262_hp_master_update(struct hda_codec *codec)
10590{
10591 struct alc_spec *spec = codec->spec;
10592 int val = spec->master_sw;
10593
10594 /* HP & line-out */
10595 snd_hda_codec_write_cache(codec, 0x1b, 0,
10596 AC_VERB_SET_PIN_WIDGET_CONTROL,
10597 val ? PIN_HP : 0);
10598 snd_hda_codec_write_cache(codec, 0x15, 0,
10599 AC_VERB_SET_PIN_WIDGET_CONTROL,
10600 val ? PIN_HP : 0);
10601 /* mono (speaker) depending on the HP jack sense */
10602 val = val && !spec->jack_present;
10603 snd_hda_codec_write_cache(codec, 0x16, 0,
10604 AC_VERB_SET_PIN_WIDGET_CONTROL,
10605 val ? PIN_OUT : 0);
10606}
10607
10608static void alc262_hp_bpc_automute(struct hda_codec *codec)
10609{
10610 struct alc_spec *spec = codec->spec;
864f92be
WF
10611
10612 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10613 alc262_hp_master_update(codec);
10614}
10615
10616static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10617{
10618 if ((res >> 26) != ALC880_HP_EVENT)
10619 return;
10620 alc262_hp_bpc_automute(codec);
10621}
10622
10623static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10624{
10625 struct alc_spec *spec = codec->spec;
864f92be
WF
10626
10627 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10628 alc262_hp_master_update(codec);
10629}
10630
10631static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10632 unsigned int res)
10633{
10634 if ((res >> 26) != ALC880_HP_EVENT)
10635 return;
10636 alc262_hp_wildwest_automute(codec);
10637}
10638
b72519b5 10639#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10640
10641static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10642 struct snd_ctl_elem_value *ucontrol)
10643{
10644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10645 struct alc_spec *spec = codec->spec;
10646 int val = !!*ucontrol->value.integer.value;
10647
10648 if (val == spec->master_sw)
10649 return 0;
10650 spec->master_sw = val;
10651 alc262_hp_master_update(codec);
10652 return 1;
10653}
10654
b72519b5
TI
10655#define ALC262_HP_MASTER_SWITCH \
10656 { \
10657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10658 .name = "Master Playback Switch", \
10659 .info = snd_ctl_boolean_mono_info, \
10660 .get = alc262_hp_master_sw_get, \
10661 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10662 }, \
10663 { \
10664 .iface = NID_MAPPING, \
10665 .name = "Master Playback Switch", \
10666 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10667 }
10668
5b0cb1d8 10669
9c7f852e 10670static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10671 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10672 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10673 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10675 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10676 HDA_OUTPUT),
10677 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10678 HDA_OUTPUT),
9c7f852e
TI
10679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10681 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10682 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10683 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10684 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10685 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10686 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10687 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10688 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10689 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10690 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10691 { } /* end */
10692};
10693
cd7509a4 10694static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10695 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10696 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10697 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10698 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10699 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10700 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10701 HDA_OUTPUT),
10702 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10703 HDA_OUTPUT),
cd7509a4
KY
10704 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10705 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10706 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10707 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10708 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10709 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10710 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10711 { } /* end */
10712};
10713
10714static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10715 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10716 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10717 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10718 { } /* end */
10719};
10720
66d2a9d6 10721/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10722static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10723{
10724 struct alc_spec *spec = codec->spec;
66d2a9d6 10725
a9fd4f3f 10726 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10727 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10728}
10729
66d2a9d6 10730static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10731 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10732 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10733 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10734 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10737 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10738 { } /* end */
10739};
10740
10741static struct hda_verb alc262_hp_t5735_verbs[] = {
10742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10744
10745 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10746 { }
10747};
10748
8c427226 10749static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
10750 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10751 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
10752 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10753 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
10754 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10755 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10756 { } /* end */
10757};
10758
10759static struct hda_verb alc262_hp_rp5700_verbs[] = {
10760 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10761 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10763 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10765 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10768 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10770 {}
10771};
10772
10773static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10774 .num_items = 1,
10775 .items = {
10776 { "Line", 0x1 },
10777 },
10778};
10779
42171c17
TI
10780/* bind hp and internal speaker mute (with plug check) as master switch */
10781static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 10782{
42171c17
TI
10783 struct alc_spec *spec = codec->spec;
10784 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10785 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10786 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10787 unsigned int mute;
0724ea2a 10788
42171c17
TI
10789 /* HP */
10790 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10791 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10792 HDA_AMP_MUTE, mute);
10793 /* mute internal speaker per jack sense */
10794 if (spec->jack_present)
10795 mute = HDA_AMP_MUTE;
10796 if (line_nid)
10797 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10798 HDA_AMP_MUTE, mute);
10799 if (speaker_nid && speaker_nid != line_nid)
10800 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 10801 HDA_AMP_MUTE, mute);
42171c17
TI
10802}
10803
10804#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10805
10806static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10807 struct snd_ctl_elem_value *ucontrol)
10808{
10809 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10810 struct alc_spec *spec = codec->spec;
10811 int val = !!*ucontrol->value.integer.value;
10812
10813 if (val == spec->master_sw)
10814 return 0;
10815 spec->master_sw = val;
10816 alc262_hippo_master_update(codec);
10817 return 1;
10818}
10819
10820#define ALC262_HIPPO_MASTER_SWITCH \
10821 { \
10822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10823 .name = "Master Playback Switch", \
10824 .info = snd_ctl_boolean_mono_info, \
10825 .get = alc262_hippo_master_sw_get, \
10826 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
10827 }, \
10828 { \
10829 .iface = NID_MAPPING, \
10830 .name = "Master Playback Switch", \
10831 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10832 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 10833 }
42171c17
TI
10834
10835static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10836 ALC262_HIPPO_MASTER_SWITCH,
10837 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10838 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10839 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10840 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10841 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10842 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10843 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10844 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10845 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10846 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10847 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10848 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10849 { } /* end */
10850};
10851
10852static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10853 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10854 ALC262_HIPPO_MASTER_SWITCH,
10855 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10856 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10857 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10858 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10862 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10863 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10864 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10865 { } /* end */
10866};
10867
10868/* mute/unmute internal speaker according to the hp jack and mute state */
10869static void alc262_hippo_automute(struct hda_codec *codec)
10870{
10871 struct alc_spec *spec = codec->spec;
10872 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 10873
864f92be 10874 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 10875 alc262_hippo_master_update(codec);
0724ea2a 10876}
5b31954e 10877
42171c17
TI
10878static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10879{
10880 if ((res >> 26) != ALC880_HP_EVENT)
10881 return;
10882 alc262_hippo_automute(codec);
10883}
10884
4f5d1706 10885static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
10886{
10887 struct alc_spec *spec = codec->spec;
10888
10889 spec->autocfg.hp_pins[0] = 0x15;
10890 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10891}
10892
4f5d1706 10893static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
10894{
10895 struct alc_spec *spec = codec->spec;
10896
10897 spec->autocfg.hp_pins[0] = 0x1b;
10898 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
10899}
10900
10901
272a527c 10902static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 10903 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 10904 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
10905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10907 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10908 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10909 { } /* end */
10910};
10911
83c34218 10912static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
10913 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10914 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
10915 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10917 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10918 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10919 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10920 { } /* end */
10921};
272a527c 10922
ba340e82
TV
10923static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10924 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10925 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10926 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10927 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10928 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10929 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10932 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10933 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10934 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10935 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10936 { } /* end */
10937};
10938
10939static struct hda_verb alc262_tyan_verbs[] = {
10940 /* Headphone automute */
10941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10943 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10944
10945 /* P11 AUX_IN, white 4-pin connector */
10946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10947 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10948 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10949 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10950
10951 {}
10952};
10953
10954/* unsolicited event for HP jack sensing */
4f5d1706 10955static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 10956{
a9fd4f3f 10957 struct alc_spec *spec = codec->spec;
ba340e82 10958
a9fd4f3f
TI
10959 spec->autocfg.hp_pins[0] = 0x1b;
10960 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
10961}
10962
ba340e82 10963
9c7f852e
TI
10964#define alc262_capture_mixer alc882_capture_mixer
10965#define alc262_capture_alt_mixer alc882_capture_alt_mixer
10966
10967/*
10968 * generic initialization of ADC, input mixers and output mixers
10969 */
10970static struct hda_verb alc262_init_verbs[] = {
10971 /*
10972 * Unmute ADC0-2 and set the default input to mic-in
10973 */
10974 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10976 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10977 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10978 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10979 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10980
cb53c626 10981 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10982 * mixer widget
f12ab1e0
TI
10983 * Note: PASD motherboards uses the Line In 2 as the input for
10984 * front panel mic (mic 2)
9c7f852e
TI
10985 */
10986 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10990 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10991 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
10992
10993 /*
df694daa
KY
10994 * Set up output mixers (0x0c - 0x0e)
10995 */
10996 /* set vol=0 to output mixers */
10997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10998 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10999 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11000 /* set up input amps for analog loopback */
11001 /* Amp Indices: DAC = 0, mixer = 1 */
11002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11003 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11004 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11005 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11008
11009 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11010 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11012 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11013 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11014 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11015
11016 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11017 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11018 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11019 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11020 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11021
df694daa
KY
11022 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11023 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11024
df694daa
KY
11025 /* FIXME: use matrix-type input source selection */
11026 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11027 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11032 /* Input mixer2 */
11033 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11034 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11035 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11036 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11037 /* Input mixer3 */
11038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11040 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11042
11043 { }
11044};
1da177e4 11045
4e555fe5
KY
11046static struct hda_verb alc262_eapd_verbs[] = {
11047 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11048 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11049 { }
11050};
11051
ccc656ce
KY
11052static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11053 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11054 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11055 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11056
11057 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11058 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11059 {}
11060};
11061
272a527c
KY
11062static struct hda_verb alc262_sony_unsol_verbs[] = {
11063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11064 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11065 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11066
11067 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11068 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11069 {}
272a527c
KY
11070};
11071
4e555fe5
KY
11072static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11073 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11074 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11075 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11078 { } /* end */
11079};
11080
11081static struct hda_verb alc262_toshiba_s06_verbs[] = {
11082 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11085 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11086 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11087 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11088 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11090 {}
11091};
11092
4f5d1706 11093static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11094{
a9fd4f3f
TI
11095 struct alc_spec *spec = codec->spec;
11096
11097 spec->autocfg.hp_pins[0] = 0x15;
11098 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11099 spec->ext_mic.pin = 0x18;
11100 spec->ext_mic.mux_idx = 0;
11101 spec->int_mic.pin = 0x12;
11102 spec->int_mic.mux_idx = 9;
11103 spec->auto_mic = 1;
4e555fe5
KY
11104}
11105
e8f9ae2a
PT
11106/*
11107 * nec model
11108 * 0x15 = headphone
11109 * 0x16 = internal speaker
11110 * 0x18 = external mic
11111 */
11112
11113static struct snd_kcontrol_new alc262_nec_mixer[] = {
11114 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11115 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11116
11117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11119 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11120
11121 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11123 { } /* end */
11124};
11125
11126static struct hda_verb alc262_nec_verbs[] = {
11127 /* Unmute Speaker */
11128 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11129
11130 /* Headphone */
11131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11132 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11133
11134 /* External mic to headphone */
11135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11136 /* External mic to speaker */
11137 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11138 {}
11139};
11140
834be88d
TI
11141/*
11142 * fujitsu model
5d9fab2d
TV
11143 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11144 * 0x1b = port replicator headphone out
834be88d
TI
11145 */
11146
11147#define ALC_HP_EVENT 0x37
11148
11149static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11150 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11151 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11152 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11154 {}
11155};
11156
0e31daf7
J
11157static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11159 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11160 {}
11161};
11162
e2595322
DC
11163static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11164 /* Front Mic pin: input vref at 50% */
11165 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11166 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11167 {}
11168};
11169
834be88d 11170static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11171 .num_items = 3,
834be88d
TI
11172 .items = {
11173 { "Mic", 0x0 },
39d3ed38 11174 { "Int Mic", 0x1 },
834be88d
TI
11175 { "CD", 0x4 },
11176 },
11177};
11178
9c7f852e
TI
11179static struct hda_input_mux alc262_HP_capture_source = {
11180 .num_items = 5,
11181 .items = {
11182 { "Mic", 0x0 },
accbe498 11183 { "Front Mic", 0x1 },
9c7f852e
TI
11184 { "Line", 0x2 },
11185 { "CD", 0x4 },
11186 { "AUX IN", 0x6 },
11187 },
11188};
11189
accbe498 11190static struct hda_input_mux alc262_HP_D7000_capture_source = {
11191 .num_items = 4,
11192 .items = {
11193 { "Mic", 0x0 },
11194 { "Front Mic", 0x2 },
11195 { "Line", 0x1 },
11196 { "CD", 0x4 },
11197 },
11198};
11199
ebc7a406 11200/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11201static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11202{
11203 struct alc_spec *spec = codec->spec;
11204 unsigned int mute;
11205
f12ab1e0 11206 if (force || !spec->sense_updated) {
864f92be
WF
11207 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11208 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11209 spec->sense_updated = 1;
11210 }
ebc7a406
TI
11211 /* unmute internal speaker only if both HPs are unplugged and
11212 * master switch is on
11213 */
11214 if (spec->jack_present)
11215 mute = HDA_AMP_MUTE;
11216 else
834be88d 11217 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11218 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11219 HDA_AMP_MUTE, mute);
834be88d
TI
11220}
11221
11222/* unsolicited event for HP jack sensing */
11223static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11224 unsigned int res)
11225{
11226 if ((res >> 26) != ALC_HP_EVENT)
11227 return;
11228 alc262_fujitsu_automute(codec, 1);
11229}
11230
ebc7a406
TI
11231static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11232{
11233 alc262_fujitsu_automute(codec, 1);
11234}
11235
834be88d 11236/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11237static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11238 .ops = &snd_hda_bind_vol,
11239 .values = {
11240 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11241 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11242 0
11243 },
11244};
834be88d 11245
0e31daf7
J
11246/* mute/unmute internal speaker according to the hp jack and mute state */
11247static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11248{
11249 struct alc_spec *spec = codec->spec;
11250 unsigned int mute;
11251
11252 if (force || !spec->sense_updated) {
864f92be 11253 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11254 spec->sense_updated = 1;
11255 }
11256 if (spec->jack_present) {
11257 /* mute internal speaker */
11258 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11259 HDA_AMP_MUTE, HDA_AMP_MUTE);
11260 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11261 HDA_AMP_MUTE, HDA_AMP_MUTE);
11262 } else {
11263 /* unmute internal speaker if necessary */
11264 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11265 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11266 HDA_AMP_MUTE, mute);
11267 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11268 HDA_AMP_MUTE, mute);
11269 }
11270}
11271
11272/* unsolicited event for HP jack sensing */
11273static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11274 unsigned int res)
11275{
11276 if ((res >> 26) != ALC_HP_EVENT)
11277 return;
11278 alc262_lenovo_3000_automute(codec, 1);
11279}
11280
8de56b7d
TI
11281static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11282 int dir, int idx, long *valp)
11283{
11284 int i, change = 0;
11285
11286 for (i = 0; i < 2; i++, valp++)
11287 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11288 HDA_AMP_MUTE,
11289 *valp ? 0 : HDA_AMP_MUTE);
11290 return change;
11291}
11292
834be88d
TI
11293/* bind hp and internal speaker mute (with plug check) */
11294static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11295 struct snd_ctl_elem_value *ucontrol)
11296{
11297 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11298 long *valp = ucontrol->value.integer.value;
11299 int change;
11300
8de56b7d
TI
11301 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11302 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11303 if (change)
11304 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11305 return change;
11306}
11307
11308static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11309 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11310 {
11311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11312 .name = "Master Playback Switch",
5e26dfd0 11313 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11314 .info = snd_hda_mixer_amp_switch_info,
11315 .get = snd_hda_mixer_amp_switch_get,
11316 .put = alc262_fujitsu_master_sw_put,
11317 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11318 },
5b0cb1d8
JK
11319 {
11320 .iface = NID_MAPPING,
11321 .name = "Master Playback Switch",
11322 .private_value = 0x1b,
11323 },
834be88d
TI
11324 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11325 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11326 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11329 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11330 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11331 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11332 { } /* end */
11333};
11334
0e31daf7
J
11335/* bind hp and internal speaker mute (with plug check) */
11336static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11337 struct snd_ctl_elem_value *ucontrol)
11338{
11339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11340 long *valp = ucontrol->value.integer.value;
11341 int change;
11342
8de56b7d 11343 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11344 if (change)
11345 alc262_lenovo_3000_automute(codec, 0);
11346 return change;
11347}
11348
11349static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11350 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11351 {
11352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11353 .name = "Master Playback Switch",
5e26dfd0 11354 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11355 .info = snd_hda_mixer_amp_switch_info,
11356 .get = snd_hda_mixer_amp_switch_get,
11357 .put = alc262_lenovo_3000_master_sw_put,
11358 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11359 },
11360 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11361 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11362 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11364 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11365 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11366 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11367 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11368 { } /* end */
11369};
11370
9f99a638
HM
11371static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11372 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11373 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11374 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11376 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11377 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11378 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11379 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11380 { } /* end */
11381};
11382
304dcaac
TI
11383/* additional init verbs for Benq laptops */
11384static struct hda_verb alc262_EAPD_verbs[] = {
11385 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11386 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11387 {}
11388};
11389
83c34218
KY
11390static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11391 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11392 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11393
11394 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11395 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11396 {}
11397};
11398
f651b50b
TD
11399/* Samsung Q1 Ultra Vista model setup */
11400static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11401 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11402 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11405 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11406 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11407 { } /* end */
11408};
11409
11410static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11411 /* output mixer */
11412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11415 /* speaker */
11416 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11417 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11418 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11419 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11420 /* HP */
f651b50b 11421 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11424 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11425 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11426 /* internal mic */
11427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11429 /* ADC, choose mic */
11430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11436 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11438 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11439 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11440 {}
11441};
11442
f651b50b
TD
11443/* mute/unmute internal speaker according to the hp jack and mute state */
11444static void alc262_ultra_automute(struct hda_codec *codec)
11445{
11446 struct alc_spec *spec = codec->spec;
11447 unsigned int mute;
f651b50b 11448
bb9f76cd
TI
11449 mute = 0;
11450 /* auto-mute only when HP is used as HP */
11451 if (!spec->cur_mux[0]) {
864f92be 11452 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11453 if (spec->jack_present)
11454 mute = HDA_AMP_MUTE;
f651b50b 11455 }
bb9f76cd
TI
11456 /* mute/unmute internal speaker */
11457 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11458 HDA_AMP_MUTE, mute);
11459 /* mute/unmute HP */
11460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11461 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11462}
11463
11464/* unsolicited event for HP jack sensing */
11465static void alc262_ultra_unsol_event(struct hda_codec *codec,
11466 unsigned int res)
11467{
11468 if ((res >> 26) != ALC880_HP_EVENT)
11469 return;
11470 alc262_ultra_automute(codec);
11471}
11472
bb9f76cd
TI
11473static struct hda_input_mux alc262_ultra_capture_source = {
11474 .num_items = 2,
11475 .items = {
11476 { "Mic", 0x1 },
11477 { "Headphone", 0x7 },
11478 },
11479};
11480
11481static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11482 struct snd_ctl_elem_value *ucontrol)
11483{
11484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11485 struct alc_spec *spec = codec->spec;
11486 int ret;
11487
54cbc9ab 11488 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11489 if (!ret)
11490 return 0;
11491 /* reprogram the HP pin as mic or HP according to the input source */
11492 snd_hda_codec_write_cache(codec, 0x15, 0,
11493 AC_VERB_SET_PIN_WIDGET_CONTROL,
11494 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11495 alc262_ultra_automute(codec); /* mute/unmute HP */
11496 return ret;
11497}
11498
11499static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11500 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11501 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11502 {
11503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11504 .name = "Capture Source",
54cbc9ab
TI
11505 .info = alc_mux_enum_info,
11506 .get = alc_mux_enum_get,
bb9f76cd
TI
11507 .put = alc262_ultra_mux_enum_put,
11508 },
5b0cb1d8
JK
11509 {
11510 .iface = NID_MAPPING,
11511 .name = "Capture Source",
11512 .private_value = 0x15,
11513 },
bb9f76cd
TI
11514 { } /* end */
11515};
11516
c3fc1f50
TI
11517/* We use two mixers depending on the output pin; 0x16 is a mono output
11518 * and thus it's bound with a different mixer.
11519 * This function returns which mixer amp should be used.
11520 */
11521static int alc262_check_volbit(hda_nid_t nid)
11522{
11523 if (!nid)
11524 return 0;
11525 else if (nid == 0x16)
11526 return 2;
11527 else
11528 return 1;
11529}
11530
11531static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11532 const char *pfx, int *vbits)
11533{
c3fc1f50
TI
11534 unsigned long val;
11535 int vbit;
11536
11537 vbit = alc262_check_volbit(nid);
11538 if (!vbit)
11539 return 0;
11540 if (*vbits & vbit) /* a volume control for this mixer already there */
11541 return 0;
11542 *vbits |= vbit;
c3fc1f50
TI
11543 if (vbit == 2)
11544 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11545 else
11546 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11547 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11548}
11549
11550static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11551 const char *pfx)
11552{
c3fc1f50
TI
11553 unsigned long val;
11554
11555 if (!nid)
11556 return 0;
c3fc1f50
TI
11557 if (nid == 0x16)
11558 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11559 else
11560 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11561 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11562}
11563
df694daa 11564/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11565static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11566 const struct auto_pin_cfg *cfg)
df694daa 11567{
c3fc1f50
TI
11568 const char *pfx;
11569 int vbits;
df694daa
KY
11570 int err;
11571
11572 spec->multiout.num_dacs = 1; /* only use one dac */
11573 spec->multiout.dac_nids = spec->private_dac_nids;
11574 spec->multiout.dac_nids[0] = 2;
11575
c3fc1f50
TI
11576 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11577 pfx = "Master";
11578 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11579 pfx = "Speaker";
11580 else
11581 pfx = "Front";
11582 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11583 if (err < 0)
11584 return err;
11585 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11586 if (err < 0)
11587 return err;
11588 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11589 if (err < 0)
11590 return err;
df694daa 11591
c3fc1f50
TI
11592 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11593 alc262_check_volbit(cfg->speaker_pins[0]) |
11594 alc262_check_volbit(cfg->hp_pins[0]);
11595 if (vbits == 1 || vbits == 2)
11596 pfx = "Master"; /* only one mixer is used */
11597 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11598 pfx = "Speaker";
11599 else
11600 pfx = "Front";
11601 vbits = 0;
11602 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11603 if (err < 0)
11604 return err;
11605 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11606 &vbits);
11607 if (err < 0)
11608 return err;
11609 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11610 &vbits);
11611 if (err < 0)
11612 return err;
f12ab1e0 11613 return 0;
df694daa
KY
11614}
11615
05f5f477 11616#define alc262_auto_create_input_ctls \
eaa9b3a7 11617 alc882_auto_create_input_ctls
df694daa
KY
11618
11619/*
11620 * generic initialization of ADC, input mixers and output mixers
11621 */
11622static struct hda_verb alc262_volume_init_verbs[] = {
11623 /*
11624 * Unmute ADC0-2 and set the default input to mic-in
11625 */
11626 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11627 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11628 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11630 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11631 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11632
cb53c626 11633 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11634 * mixer widget
f12ab1e0
TI
11635 * Note: PASD motherboards uses the Line In 2 as the input for
11636 * front panel mic (mic 2)
df694daa
KY
11637 */
11638 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11644
11645 /*
11646 * Set up output mixers (0x0c - 0x0f)
11647 */
11648 /* set vol=0 to output mixers */
11649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11652
df694daa
KY
11653 /* set up input amps for analog loopback */
11654 /* Amp Indices: DAC = 0, mixer = 1 */
11655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11657 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11658 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11659 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11660 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11661
11662 /* FIXME: use matrix-type input source selection */
11663 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11664 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11665 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11669 /* Input mixer2 */
11670 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11672 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11674 /* Input mixer3 */
11675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11679
11680 { }
11681};
11682
9c7f852e
TI
11683static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11684 /*
11685 * Unmute ADC0-2 and set the default input to mic-in
11686 */
11687 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11689 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11690 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11691 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11692 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11693
cb53c626 11694 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11695 * mixer widget
f12ab1e0
TI
11696 * Note: PASD motherboards uses the Line In 2 as the input for
11697 * front panel mic (mic 2)
9c7f852e
TI
11698 */
11699 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11701 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11702 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11703 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11707
9c7f852e
TI
11708 /*
11709 * Set up output mixers (0x0c - 0x0e)
11710 */
11711 /* set vol=0 to output mixers */
11712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11715
11716 /* set up input amps for analog loopback */
11717 /* Amp Indices: DAC = 0, mixer = 1 */
11718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11724
ce875f07 11725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11727 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11728
11729 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11731
11732 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11734
11735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11736 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11737 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11739 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11740
0e4835c1 11741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11744 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11745 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11746 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11747
11748
11749 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
11750 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11751 /* Input mixer1: only unmute Mic */
9c7f852e 11752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11753 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11761 /* Input mixer2 */
11762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11768 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11769 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11770 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11771 /* Input mixer3 */
11772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 11781
ce875f07
TI
11782 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11783
9c7f852e
TI
11784 { }
11785};
11786
cd7509a4
KY
11787static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11788 /*
11789 * Unmute ADC0-2 and set the default input to mic-in
11790 */
11791 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11793 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11794 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11795 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11796 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11797
cb53c626 11798 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
11799 * mixer widget
11800 * Note: PASD motherboards uses the Line In 2 as the input for front
11801 * panel mic (mic 2)
11802 */
11803 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11804 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11805 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11806 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11807 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11808 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11809 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11810 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
11812 /*
11813 * Set up output mixers (0x0c - 0x0e)
11814 */
11815 /* set vol=0 to output mixers */
11816 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11817 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11818 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11819
11820 /* set up input amps for analog loopback */
11821 /* Amp Indices: DAC = 0, mixer = 1 */
11822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11824 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11825 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11826 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11827 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11828
11829
11830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11831 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11833 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11834 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11835 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11836 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11837
11838 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11839 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11840
11841 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11843
11844 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11845 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11846 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11847 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11848 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11849 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11850
11851 /* FIXME: use matrix-type input source selection */
11852 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11853 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11854 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11855 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11859 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11860 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11861 /* Input mixer2 */
11862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11863 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11864 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11865 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11866 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11867 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11868 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11869 /* Input mixer3 */
11870 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11871 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11875 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11877
ce875f07
TI
11878 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11879
cd7509a4
KY
11880 { }
11881};
11882
9f99a638
HM
11883static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11884
11885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11886 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11887 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11888
11889 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11890 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11891 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11892 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11893
11894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11895 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11896 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11897 {}
11898};
11899
11900
cb53c626
TI
11901#ifdef CONFIG_SND_HDA_POWER_SAVE
11902#define alc262_loopbacks alc880_loopbacks
11903#endif
11904
def319f9 11905/* pcm configuration: identical with ALC880 */
df694daa
KY
11906#define alc262_pcm_analog_playback alc880_pcm_analog_playback
11907#define alc262_pcm_analog_capture alc880_pcm_analog_capture
11908#define alc262_pcm_digital_playback alc880_pcm_digital_playback
11909#define alc262_pcm_digital_capture alc880_pcm_digital_capture
11910
11911/*
11912 * BIOS auto configuration
11913 */
11914static int alc262_parse_auto_config(struct hda_codec *codec)
11915{
11916 struct alc_spec *spec = codec->spec;
11917 int err;
11918 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11919
f12ab1e0
TI
11920 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11921 alc262_ignore);
11922 if (err < 0)
df694daa 11923 return err;
e64f14f4 11924 if (!spec->autocfg.line_outs) {
0852d7a6 11925 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
11926 spec->multiout.max_channels = 2;
11927 spec->no_analog = 1;
11928 goto dig_only;
11929 }
df694daa 11930 return 0; /* can't find valid BIOS pin config */
e64f14f4 11931 }
f12ab1e0
TI
11932 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11933 if (err < 0)
11934 return err;
05f5f477 11935 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 11936 if (err < 0)
df694daa
KY
11937 return err;
11938
11939 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11940
e64f14f4 11941 dig_only:
0852d7a6 11942 if (spec->autocfg.dig_outs) {
df694daa 11943 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 11944 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 11945 }
df694daa
KY
11946 if (spec->autocfg.dig_in_pin)
11947 spec->dig_in_nid = ALC262_DIGIN_NID;
11948
603c4019 11949 if (spec->kctls.list)
d88897ea 11950 add_mixer(spec, spec->kctls.list);
df694daa 11951
d88897ea 11952 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 11953 spec->num_mux_defs = 1;
61b9b9b1 11954 spec->input_mux = &spec->private_imux[0];
df694daa 11955
776e184e
TI
11956 err = alc_auto_add_mic_boost(codec);
11957 if (err < 0)
11958 return err;
11959
6227cdce 11960 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 11961
df694daa
KY
11962 return 1;
11963}
11964
11965#define alc262_auto_init_multi_out alc882_auto_init_multi_out
11966#define alc262_auto_init_hp_out alc882_auto_init_hp_out
11967#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 11968#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
11969
11970
11971/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 11972static void alc262_auto_init(struct hda_codec *codec)
df694daa 11973{
f6c7e546 11974 struct alc_spec *spec = codec->spec;
df694daa
KY
11975 alc262_auto_init_multi_out(codec);
11976 alc262_auto_init_hp_out(codec);
11977 alc262_auto_init_analog_input(codec);
f511b01c 11978 alc262_auto_init_input_src(codec);
f6c7e546 11979 if (spec->unsol_event)
7fb0d78f 11980 alc_inithook(codec);
df694daa
KY
11981}
11982
11983/*
11984 * configuration and preset
11985 */
f5fcc13c
TI
11986static const char *alc262_models[ALC262_MODEL_LAST] = {
11987 [ALC262_BASIC] = "basic",
11988 [ALC262_HIPPO] = "hippo",
11989 [ALC262_HIPPO_1] = "hippo_1",
11990 [ALC262_FUJITSU] = "fujitsu",
11991 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 11992 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 11993 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 11994 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 11995 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
11996 [ALC262_BENQ_T31] = "benq-t31",
11997 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 11998 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 11999 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12000 [ALC262_ULTRA] = "ultra",
0e31daf7 12001 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12002 [ALC262_NEC] = "nec",
ba340e82 12003 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12004 [ALC262_AUTO] = "auto",
12005};
12006
12007static struct snd_pci_quirk alc262_cfg_tbl[] = {
12008 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12009 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12010 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12011 ALC262_HP_BPC),
12012 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12013 ALC262_HP_BPC),
53eff7e1
TI
12014 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12015 ALC262_HP_BPC),
cd7509a4 12016 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12017 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12018 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12019 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12020 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12021 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12022 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12023 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12024 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12025 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12026 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12027 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12028 ALC262_HP_TC_T5735),
8c427226 12029 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12030 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12031 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12032 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12033 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12034 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12035 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12036 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12037#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12038 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12039 ALC262_SONY_ASSAMD),
c5b5165c 12040#endif
36ca6e13 12041 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12042 ALC262_TOSHIBA_RX1),
80ffe869 12043 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12044 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12045 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12046 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12047 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12048 ALC262_ULTRA),
3e420e78 12049 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12050 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12051 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12052 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12053 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12054 {}
12055};
12056
12057static struct alc_config_preset alc262_presets[] = {
12058 [ALC262_BASIC] = {
12059 .mixers = { alc262_base_mixer },
12060 .init_verbs = { alc262_init_verbs },
12061 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12062 .dac_nids = alc262_dac_nids,
12063 .hp_nid = 0x03,
12064 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12065 .channel_mode = alc262_modes,
a3bcba38 12066 .input_mux = &alc262_capture_source,
df694daa 12067 },
ccc656ce 12068 [ALC262_HIPPO] = {
42171c17 12069 .mixers = { alc262_hippo_mixer },
6732bd0d 12070 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12071 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12072 .dac_nids = alc262_dac_nids,
12073 .hp_nid = 0x03,
12074 .dig_out_nid = ALC262_DIGOUT_NID,
12075 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12076 .channel_mode = alc262_modes,
12077 .input_mux = &alc262_capture_source,
12078 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12079 .setup = alc262_hippo_setup,
12080 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12081 },
12082 [ALC262_HIPPO_1] = {
12083 .mixers = { alc262_hippo1_mixer },
12084 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12085 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12086 .dac_nids = alc262_dac_nids,
12087 .hp_nid = 0x02,
12088 .dig_out_nid = ALC262_DIGOUT_NID,
12089 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12090 .channel_mode = alc262_modes,
12091 .input_mux = &alc262_capture_source,
42171c17 12092 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12093 .setup = alc262_hippo1_setup,
12094 .init_hook = alc262_hippo_automute,
ccc656ce 12095 },
834be88d
TI
12096 [ALC262_FUJITSU] = {
12097 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12098 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12099 alc262_fujitsu_unsol_verbs },
834be88d
TI
12100 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12101 .dac_nids = alc262_dac_nids,
12102 .hp_nid = 0x03,
12103 .dig_out_nid = ALC262_DIGOUT_NID,
12104 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12105 .channel_mode = alc262_modes,
12106 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12107 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12108 .init_hook = alc262_fujitsu_init_hook,
834be88d 12109 },
9c7f852e
TI
12110 [ALC262_HP_BPC] = {
12111 .mixers = { alc262_HP_BPC_mixer },
12112 .init_verbs = { alc262_HP_BPC_init_verbs },
12113 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12114 .dac_nids = alc262_dac_nids,
12115 .hp_nid = 0x03,
12116 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12117 .channel_mode = alc262_modes,
12118 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12119 .unsol_event = alc262_hp_bpc_unsol_event,
12120 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12121 },
cd7509a4
KY
12122 [ALC262_HP_BPC_D7000_WF] = {
12123 .mixers = { alc262_HP_BPC_WildWest_mixer },
12124 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12125 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12126 .dac_nids = alc262_dac_nids,
12127 .hp_nid = 0x03,
12128 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12129 .channel_mode = alc262_modes,
accbe498 12130 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12131 .unsol_event = alc262_hp_wildwest_unsol_event,
12132 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12133 },
cd7509a4
KY
12134 [ALC262_HP_BPC_D7000_WL] = {
12135 .mixers = { alc262_HP_BPC_WildWest_mixer,
12136 alc262_HP_BPC_WildWest_option_mixer },
12137 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12138 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12139 .dac_nids = alc262_dac_nids,
12140 .hp_nid = 0x03,
12141 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12142 .channel_mode = alc262_modes,
accbe498 12143 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12144 .unsol_event = alc262_hp_wildwest_unsol_event,
12145 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12146 },
66d2a9d6
KY
12147 [ALC262_HP_TC_T5735] = {
12148 .mixers = { alc262_hp_t5735_mixer },
12149 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12150 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12151 .dac_nids = alc262_dac_nids,
12152 .hp_nid = 0x03,
12153 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12154 .channel_mode = alc262_modes,
12155 .input_mux = &alc262_capture_source,
dc99be47 12156 .unsol_event = alc_sku_unsol_event,
4f5d1706 12157 .setup = alc262_hp_t5735_setup,
dc99be47 12158 .init_hook = alc_inithook,
8c427226
KY
12159 },
12160 [ALC262_HP_RP5700] = {
12161 .mixers = { alc262_hp_rp5700_mixer },
12162 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12163 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12164 .dac_nids = alc262_dac_nids,
12165 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12166 .channel_mode = alc262_modes,
12167 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12168 },
304dcaac
TI
12169 [ALC262_BENQ_ED8] = {
12170 .mixers = { alc262_base_mixer },
12171 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12172 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12173 .dac_nids = alc262_dac_nids,
12174 .hp_nid = 0x03,
12175 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12176 .channel_mode = alc262_modes,
12177 .input_mux = &alc262_capture_source,
f12ab1e0 12178 },
272a527c
KY
12179 [ALC262_SONY_ASSAMD] = {
12180 .mixers = { alc262_sony_mixer },
12181 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12182 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12183 .dac_nids = alc262_dac_nids,
12184 .hp_nid = 0x02,
12185 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12186 .channel_mode = alc262_modes,
12187 .input_mux = &alc262_capture_source,
12188 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12189 .setup = alc262_hippo_setup,
12190 .init_hook = alc262_hippo_automute,
83c34218
KY
12191 },
12192 [ALC262_BENQ_T31] = {
12193 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12194 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12195 alc_hp15_unsol_verbs },
83c34218
KY
12196 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12197 .dac_nids = alc262_dac_nids,
12198 .hp_nid = 0x03,
12199 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12200 .channel_mode = alc262_modes,
12201 .input_mux = &alc262_capture_source,
12202 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12203 .setup = alc262_hippo_setup,
12204 .init_hook = alc262_hippo_automute,
ea1fb29a 12205 },
f651b50b 12206 [ALC262_ULTRA] = {
f9e336f6
TI
12207 .mixers = { alc262_ultra_mixer },
12208 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12209 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12210 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12211 .dac_nids = alc262_dac_nids,
f651b50b
TD
12212 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12213 .channel_mode = alc262_modes,
12214 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12215 .adc_nids = alc262_adc_nids, /* ADC0 */
12216 .capsrc_nids = alc262_capsrc_nids,
12217 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12218 .unsol_event = alc262_ultra_unsol_event,
12219 .init_hook = alc262_ultra_automute,
12220 },
0e31daf7
J
12221 [ALC262_LENOVO_3000] = {
12222 .mixers = { alc262_lenovo_3000_mixer },
12223 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12224 alc262_lenovo_3000_unsol_verbs,
12225 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12226 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12227 .dac_nids = alc262_dac_nids,
12228 .hp_nid = 0x03,
12229 .dig_out_nid = ALC262_DIGOUT_NID,
12230 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12231 .channel_mode = alc262_modes,
12232 .input_mux = &alc262_fujitsu_capture_source,
12233 .unsol_event = alc262_lenovo_3000_unsol_event,
12234 },
e8f9ae2a
PT
12235 [ALC262_NEC] = {
12236 .mixers = { alc262_nec_mixer },
12237 .init_verbs = { alc262_nec_verbs },
12238 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12239 .dac_nids = alc262_dac_nids,
12240 .hp_nid = 0x03,
12241 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12242 .channel_mode = alc262_modes,
12243 .input_mux = &alc262_capture_source,
12244 },
4e555fe5
KY
12245 [ALC262_TOSHIBA_S06] = {
12246 .mixers = { alc262_toshiba_s06_mixer },
12247 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12248 alc262_eapd_verbs },
12249 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12250 .capsrc_nids = alc262_dmic_capsrc_nids,
12251 .dac_nids = alc262_dac_nids,
12252 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12253 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12254 .dig_out_nid = ALC262_DIGOUT_NID,
12255 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12256 .channel_mode = alc262_modes,
4f5d1706
TI
12257 .unsol_event = alc_sku_unsol_event,
12258 .setup = alc262_toshiba_s06_setup,
12259 .init_hook = alc_inithook,
4e555fe5 12260 },
9f99a638
HM
12261 [ALC262_TOSHIBA_RX1] = {
12262 .mixers = { alc262_toshiba_rx1_mixer },
12263 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12264 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12265 .dac_nids = alc262_dac_nids,
12266 .hp_nid = 0x03,
12267 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12268 .channel_mode = alc262_modes,
12269 .input_mux = &alc262_capture_source,
12270 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12271 .setup = alc262_hippo_setup,
12272 .init_hook = alc262_hippo_automute,
9f99a638 12273 },
ba340e82
TV
12274 [ALC262_TYAN] = {
12275 .mixers = { alc262_tyan_mixer },
12276 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12277 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12278 .dac_nids = alc262_dac_nids,
12279 .hp_nid = 0x02,
12280 .dig_out_nid = ALC262_DIGOUT_NID,
12281 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12282 .channel_mode = alc262_modes,
12283 .input_mux = &alc262_capture_source,
a9fd4f3f 12284 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12285 .setup = alc262_tyan_setup,
12286 .init_hook = alc_automute_amp,
ba340e82 12287 },
df694daa
KY
12288};
12289
12290static int patch_alc262(struct hda_codec *codec)
12291{
12292 struct alc_spec *spec;
12293 int board_config;
12294 int err;
12295
dc041e0b 12296 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12297 if (spec == NULL)
12298 return -ENOMEM;
12299
12300 codec->spec = spec;
12301#if 0
f12ab1e0
TI
12302 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12303 * under-run
12304 */
df694daa
KY
12305 {
12306 int tmp;
12307 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12308 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12309 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12310 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12311 }
12312#endif
da00c244 12313 alc_auto_parse_customize_define(codec);
df694daa 12314
2c3bf9ab
TI
12315 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12316
f5fcc13c
TI
12317 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12318 alc262_models,
12319 alc262_cfg_tbl);
cd7509a4 12320
f5fcc13c 12321 if (board_config < 0) {
9a11f1aa
TI
12322 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12323 codec->chip_name);
df694daa
KY
12324 board_config = ALC262_AUTO;
12325 }
12326
12327 if (board_config == ALC262_AUTO) {
12328 /* automatic parse from the BIOS config */
12329 err = alc262_parse_auto_config(codec);
12330 if (err < 0) {
12331 alc_free(codec);
12332 return err;
f12ab1e0 12333 } else if (!err) {
9c7f852e
TI
12334 printk(KERN_INFO
12335 "hda_codec: Cannot set up configuration "
12336 "from BIOS. Using base mode...\n");
df694daa
KY
12337 board_config = ALC262_BASIC;
12338 }
12339 }
12340
07eba61d
TI
12341 if (!spec->no_analog) {
12342 err = snd_hda_attach_beep_device(codec, 0x1);
12343 if (err < 0) {
12344 alc_free(codec);
12345 return err;
12346 }
680cd536
KK
12347 }
12348
df694daa 12349 if (board_config != ALC262_AUTO)
e9c364c0 12350 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12351
df694daa
KY
12352 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12353 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12354
df694daa
KY
12355 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12356 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12357
f12ab1e0 12358 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12359 int i;
12360 /* check whether the digital-mic has to be supported */
12361 for (i = 0; i < spec->input_mux->num_items; i++) {
12362 if (spec->input_mux->items[i].index >= 9)
12363 break;
12364 }
12365 if (i < spec->input_mux->num_items) {
12366 /* use only ADC0 */
12367 spec->adc_nids = alc262_dmic_adc_nids;
12368 spec->num_adc_nids = 1;
12369 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12370 } else {
8c927b4a
TI
12371 /* all analog inputs */
12372 /* check whether NID 0x07 is valid */
12373 unsigned int wcap = get_wcaps(codec, 0x07);
12374
12375 /* get type */
a22d543a 12376 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12377 if (wcap != AC_WID_AUD_IN) {
12378 spec->adc_nids = alc262_adc_nids_alt;
12379 spec->num_adc_nids =
12380 ARRAY_SIZE(alc262_adc_nids_alt);
12381 spec->capsrc_nids = alc262_capsrc_nids_alt;
12382 } else {
12383 spec->adc_nids = alc262_adc_nids;
12384 spec->num_adc_nids =
12385 ARRAY_SIZE(alc262_adc_nids);
12386 spec->capsrc_nids = alc262_capsrc_nids;
12387 }
df694daa
KY
12388 }
12389 }
e64f14f4 12390 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12391 set_capture_mixer(codec);
da00c244 12392 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
07eba61d 12393 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12394
2134ea4f
TI
12395 spec->vmaster_nid = 0x0c;
12396
df694daa
KY
12397 codec->patch_ops = alc_patch_ops;
12398 if (board_config == ALC262_AUTO)
ae6b813a 12399 spec->init_hook = alc262_auto_init;
cb53c626
TI
12400#ifdef CONFIG_SND_HDA_POWER_SAVE
12401 if (!spec->loopback.amplist)
12402 spec->loopback.amplist = alc262_loopbacks;
12403#endif
ea1fb29a 12404
df694daa
KY
12405 return 0;
12406}
12407
a361d84b
KY
12408/*
12409 * ALC268 channel source setting (2 channel)
12410 */
12411#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12412#define alc268_modes alc260_modes
ea1fb29a 12413
a361d84b
KY
12414static hda_nid_t alc268_dac_nids[2] = {
12415 /* front, hp */
12416 0x02, 0x03
12417};
12418
12419static hda_nid_t alc268_adc_nids[2] = {
12420 /* ADC0-1 */
12421 0x08, 0x07
12422};
12423
12424static hda_nid_t alc268_adc_nids_alt[1] = {
12425 /* ADC0 */
12426 0x08
12427};
12428
e1406348
TI
12429static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12430
a361d84b
KY
12431static struct snd_kcontrol_new alc268_base_mixer[] = {
12432 /* output mixer control */
12433 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12434 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12435 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12437 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12438 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12439 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12440 { }
12441};
12442
42171c17
TI
12443static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12444 /* output mixer control */
12445 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12446 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12447 ALC262_HIPPO_MASTER_SWITCH,
12448 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12449 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12450 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12451 { }
12452};
12453
aef9d318
TI
12454/* bind Beep switches of both NID 0x0f and 0x10 */
12455static struct hda_bind_ctls alc268_bind_beep_sw = {
12456 .ops = &snd_hda_bind_sw,
12457 .values = {
12458 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12459 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12460 0
12461 },
12462};
12463
12464static struct snd_kcontrol_new alc268_beep_mixer[] = {
12465 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12466 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12467 { }
12468};
12469
d1a991a6
KY
12470static struct hda_verb alc268_eapd_verbs[] = {
12471 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12472 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12473 { }
12474};
12475
d273809e 12476/* Toshiba specific */
d273809e
TI
12477static struct hda_verb alc268_toshiba_verbs[] = {
12478 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12479 { } /* end */
12480};
12481
12482/* Acer specific */
889c4395 12483/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12484static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12485 .ops = &snd_hda_bind_vol,
12486 .values = {
12487 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12488 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12489 0
12490 },
12491};
12492
889c4395
TI
12493/* mute/unmute internal speaker according to the hp jack and mute state */
12494static void alc268_acer_automute(struct hda_codec *codec, int force)
12495{
12496 struct alc_spec *spec = codec->spec;
12497 unsigned int mute;
12498
12499 if (force || !spec->sense_updated) {
864f92be 12500 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12501 spec->sense_updated = 1;
12502 }
12503 if (spec->jack_present)
12504 mute = HDA_AMP_MUTE; /* mute internal speaker */
12505 else /* unmute internal speaker if necessary */
12506 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12507 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12508 HDA_AMP_MUTE, mute);
12509}
12510
12511
12512/* bind hp and internal speaker mute (with plug check) */
12513static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12514 struct snd_ctl_elem_value *ucontrol)
12515{
12516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12517 long *valp = ucontrol->value.integer.value;
12518 int change;
12519
8de56b7d 12520 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12521 if (change)
12522 alc268_acer_automute(codec, 0);
12523 return change;
12524}
d273809e 12525
8ef355da
KY
12526static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12527 /* output mixer control */
12528 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12529 {
12530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12531 .name = "Master Playback Switch",
5e26dfd0 12532 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12533 .info = snd_hda_mixer_amp_switch_info,
12534 .get = snd_hda_mixer_amp_switch_get,
12535 .put = alc268_acer_master_sw_put,
12536 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12537 },
12538 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12539 { }
12540};
12541
d273809e
TI
12542static struct snd_kcontrol_new alc268_acer_mixer[] = {
12543 /* output mixer control */
12544 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12545 {
12546 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12547 .name = "Master Playback Switch",
5e26dfd0 12548 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12549 .info = snd_hda_mixer_amp_switch_info,
12550 .get = snd_hda_mixer_amp_switch_get,
12551 .put = alc268_acer_master_sw_put,
12552 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12553 },
33bf17ab
TI
12554 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12555 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12556 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12557 { }
12558};
12559
c238b4f4
TI
12560static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12561 /* output mixer control */
12562 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12563 {
12564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12565 .name = "Master Playback Switch",
5e26dfd0 12566 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12567 .info = snd_hda_mixer_amp_switch_info,
12568 .get = snd_hda_mixer_amp_switch_get,
12569 .put = alc268_acer_master_sw_put,
12570 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12571 },
12572 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12573 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12574 { }
12575};
12576
8ef355da
KY
12577static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12578 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12580 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12581 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12582 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12584 { }
12585};
12586
d273809e 12587static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12588 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12589 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12593 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12594 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12595 { }
12596};
12597
12598/* unsolicited event for HP jack sensing */
42171c17 12599#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12600#define alc268_toshiba_setup alc262_hippo_setup
12601#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12602
12603static void alc268_acer_unsol_event(struct hda_codec *codec,
12604 unsigned int res)
12605{
889c4395 12606 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12607 return;
12608 alc268_acer_automute(codec, 1);
12609}
12610
889c4395
TI
12611static void alc268_acer_init_hook(struct hda_codec *codec)
12612{
12613 alc268_acer_automute(codec, 1);
12614}
12615
8ef355da
KY
12616/* toggle speaker-output according to the hp-jack state */
12617static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12618{
12619 unsigned int present;
12620 unsigned char bits;
12621
864f92be 12622 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12623 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12624 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12625 HDA_AMP_MUTE, bits);
8ef355da 12626 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12627 HDA_AMP_MUTE, bits);
8ef355da
KY
12628}
12629
8ef355da
KY
12630static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12631 unsigned int res)
12632{
4f5d1706
TI
12633 switch (res >> 26) {
12634 case ALC880_HP_EVENT:
8ef355da 12635 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12636 break;
12637 case ALC880_MIC_EVENT:
12638 alc_mic_automute(codec);
12639 break;
12640 }
12641}
12642
12643static void alc268_acer_lc_setup(struct hda_codec *codec)
12644{
12645 struct alc_spec *spec = codec->spec;
12646 spec->ext_mic.pin = 0x18;
12647 spec->ext_mic.mux_idx = 0;
12648 spec->int_mic.pin = 0x12;
12649 spec->int_mic.mux_idx = 6;
12650 spec->auto_mic = 1;
8ef355da
KY
12651}
12652
12653static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12654{
12655 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12656 alc_mic_automute(codec);
8ef355da
KY
12657}
12658
3866f0b0
TI
12659static struct snd_kcontrol_new alc268_dell_mixer[] = {
12660 /* output mixer control */
12661 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12662 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12663 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12665 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12666 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12667 { }
12668};
12669
12670static struct hda_verb alc268_dell_verbs[] = {
12671 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12673 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12674 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12675 { }
12676};
12677
12678/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12679static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12680{
a9fd4f3f 12681 struct alc_spec *spec = codec->spec;
3866f0b0 12682
a9fd4f3f
TI
12683 spec->autocfg.hp_pins[0] = 0x15;
12684 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12685 spec->ext_mic.pin = 0x18;
12686 spec->ext_mic.mux_idx = 0;
12687 spec->int_mic.pin = 0x19;
12688 spec->int_mic.mux_idx = 1;
12689 spec->auto_mic = 1;
3866f0b0
TI
12690}
12691
eb5a6621
HRK
12692static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12693 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12694 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12697 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12698 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12699 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12700 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12701 { }
12702};
12703
12704static struct hda_verb alc267_quanta_il1_verbs[] = {
12705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12706 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12707 { }
12708};
12709
4f5d1706 12710static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12711{
a9fd4f3f 12712 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12713 spec->autocfg.hp_pins[0] = 0x15;
12714 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12715 spec->ext_mic.pin = 0x18;
12716 spec->ext_mic.mux_idx = 0;
12717 spec->int_mic.pin = 0x19;
12718 spec->int_mic.mux_idx = 1;
12719 spec->auto_mic = 1;
eb5a6621
HRK
12720}
12721
a361d84b
KY
12722/*
12723 * generic initialization of ADC, input mixers and output mixers
12724 */
12725static struct hda_verb alc268_base_init_verbs[] = {
12726 /* Unmute DAC0-1 and set vol = 0 */
12727 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12728 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12729
12730 /*
12731 * Set up output mixers (0x0c - 0x0e)
12732 */
12733 /* set vol=0 to output mixers */
12734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12735 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12736
12737 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12738 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739
12740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12742 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12745 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12746 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12747 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12748
12749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12754
12755 /* set PCBEEP vol = 0, mute connections */
12756 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12758 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12759
a9b3aa8a 12760 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12761
a9b3aa8a
JZ
12762 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12764 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 12766
a361d84b
KY
12767 { }
12768};
12769
12770/*
12771 * generic initialization of ADC, input mixers and output mixers
12772 */
12773static struct hda_verb alc268_volume_init_verbs[] = {
12774 /* set output DAC */
4cfb91c6
TI
12775 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12776 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12777
12778 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12779 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12781 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12782 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12783
a361d84b 12784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12785 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12786 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12787
12788 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12790
aef9d318
TI
12791 /* set PCBEEP vol = 0, mute connections */
12792 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12794 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
12795
12796 { }
12797};
12798
fdbc6626
TI
12799static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12800 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12801 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12802 { } /* end */
12803};
12804
a361d84b
KY
12805static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12806 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12807 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 12808 _DEFINE_CAPSRC(1),
a361d84b
KY
12809 { } /* end */
12810};
12811
12812static struct snd_kcontrol_new alc268_capture_mixer[] = {
12813 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12814 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12815 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12816 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 12817 _DEFINE_CAPSRC(2),
a361d84b
KY
12818 { } /* end */
12819};
12820
12821static struct hda_input_mux alc268_capture_source = {
12822 .num_items = 4,
12823 .items = {
12824 { "Mic", 0x0 },
12825 { "Front Mic", 0x1 },
12826 { "Line", 0x2 },
12827 { "CD", 0x3 },
12828 },
12829};
12830
0ccb541c 12831static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
12832 .num_items = 3,
12833 .items = {
12834 { "Mic", 0x0 },
12835 { "Internal Mic", 0x1 },
12836 { "Line", 0x2 },
12837 },
12838};
12839
12840static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
12841 .num_items = 3,
12842 .items = {
12843 { "Mic", 0x0 },
12844 { "Internal Mic", 0x6 },
12845 { "Line", 0x2 },
12846 },
12847};
12848
86c53bd2
JW
12849#ifdef CONFIG_SND_DEBUG
12850static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
12851 /* Volume widgets */
12852 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12853 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12854 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12855 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12856 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12857 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12858 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12859 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12860 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12861 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12862 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12863 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12864 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
12865 /* The below appears problematic on some hardwares */
12866 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
12867 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12868 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12869 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12870 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12871
12872 /* Modes for retasking pin widgets */
12873 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12874 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12875 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12876 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12877
12878 /* Controls for GPIO pins, assuming they are configured as outputs */
12879 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12880 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12881 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12882 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12883
12884 /* Switches to allow the digital SPDIF output pin to be enabled.
12885 * The ALC268 does not have an SPDIF input.
12886 */
12887 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12888
12889 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12890 * this output to turn on an external amplifier.
12891 */
12892 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12893 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12894
12895 { } /* end */
12896};
12897#endif
12898
a361d84b
KY
12899/* create input playback/capture controls for the given pin */
12900static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12901 const char *ctlname, int idx)
12902{
3f3b7c1a 12903 hda_nid_t dac;
a361d84b
KY
12904 int err;
12905
3f3b7c1a
TI
12906 switch (nid) {
12907 case 0x14:
12908 case 0x16:
12909 dac = 0x02;
12910 break;
12911 case 0x15:
12912 dac = 0x03;
12913 break;
12914 default:
12915 return 0;
12916 }
12917 if (spec->multiout.dac_nids[0] != dac &&
12918 spec->multiout.dac_nids[1] != dac) {
0afe5f89 12919 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 12920 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
12921 HDA_OUTPUT));
12922 if (err < 0)
12923 return err;
3f3b7c1a
TI
12924 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12925 }
12926
3f3b7c1a 12927 if (nid != 0x16)
0afe5f89 12928 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 12929 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 12930 else /* mono */
0afe5f89 12931 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 12932 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
12933 if (err < 0)
12934 return err;
12935 return 0;
12936}
12937
12938/* add playback controls from the parsed DAC table */
12939static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12940 const struct auto_pin_cfg *cfg)
12941{
12942 hda_nid_t nid;
12943 int err;
12944
a361d84b 12945 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
12946
12947 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
12948 if (nid) {
12949 const char *name;
12950 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12951 name = "Speaker";
12952 else
12953 name = "Front";
12954 err = alc268_new_analog_output(spec, nid, name, 0);
12955 if (err < 0)
12956 return err;
12957 }
a361d84b
KY
12958
12959 nid = cfg->speaker_pins[0];
12960 if (nid == 0x1d) {
0afe5f89 12961 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
12962 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12963 if (err < 0)
12964 return err;
3f3b7c1a
TI
12965 } else {
12966 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12967 if (err < 0)
12968 return err;
a361d84b
KY
12969 }
12970 nid = cfg->hp_pins[0];
3f3b7c1a
TI
12971 if (nid) {
12972 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12973 if (err < 0)
12974 return err;
12975 }
a361d84b
KY
12976
12977 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12978 if (nid == 0x16) {
0afe5f89 12979 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 12980 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
12981 if (err < 0)
12982 return err;
12983 }
ea1fb29a 12984 return 0;
a361d84b
KY
12985}
12986
12987/* create playback/capture controls for input pins */
05f5f477 12988static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
12989 const struct auto_pin_cfg *cfg)
12990{
05f5f477 12991 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
12992}
12993
e9af4f36
TI
12994static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12995 hda_nid_t nid, int pin_type)
12996{
12997 int idx;
12998
12999 alc_set_pin_output(codec, nid, pin_type);
13000 if (nid == 0x14 || nid == 0x16)
13001 idx = 0;
13002 else
13003 idx = 1;
13004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13005}
13006
13007static void alc268_auto_init_multi_out(struct hda_codec *codec)
13008{
13009 struct alc_spec *spec = codec->spec;
13010 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13011 if (nid) {
13012 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13013 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13014 }
13015}
13016
13017static void alc268_auto_init_hp_out(struct hda_codec *codec)
13018{
13019 struct alc_spec *spec = codec->spec;
13020 hda_nid_t pin;
13021
13022 pin = spec->autocfg.hp_pins[0];
13023 if (pin)
13024 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13025 pin = spec->autocfg.speaker_pins[0];
13026 if (pin)
13027 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13028}
13029
a361d84b
KY
13030static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13031{
13032 struct alc_spec *spec = codec->spec;
13033 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13034 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13035 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13036 unsigned int dac_vol1, dac_vol2;
13037
e9af4f36 13038 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13039 snd_hda_codec_write(codec, speaker_nid, 0,
13040 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13041 /* mute mixer inputs from 0x1d */
a361d84b
KY
13042 snd_hda_codec_write(codec, 0x0f, 0,
13043 AC_VERB_SET_AMP_GAIN_MUTE,
13044 AMP_IN_UNMUTE(1));
13045 snd_hda_codec_write(codec, 0x10, 0,
13046 AC_VERB_SET_AMP_GAIN_MUTE,
13047 AMP_IN_UNMUTE(1));
13048 } else {
e9af4f36 13049 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13050 snd_hda_codec_write(codec, 0x0f, 0,
13051 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13052 snd_hda_codec_write(codec, 0x10, 0,
13053 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13054 }
13055
13056 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13057 if (line_nid == 0x14)
a361d84b
KY
13058 dac_vol2 = AMP_OUT_ZERO;
13059 else if (line_nid == 0x15)
13060 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13061 if (hp_nid == 0x14)
a361d84b
KY
13062 dac_vol2 = AMP_OUT_ZERO;
13063 else if (hp_nid == 0x15)
13064 dac_vol1 = AMP_OUT_ZERO;
13065 if (line_nid != 0x16 || hp_nid != 0x16 ||
13066 spec->autocfg.line_out_pins[1] != 0x16 ||
13067 spec->autocfg.line_out_pins[2] != 0x16)
13068 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13069
13070 snd_hda_codec_write(codec, 0x02, 0,
13071 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13072 snd_hda_codec_write(codec, 0x03, 0,
13073 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13074}
13075
def319f9 13076/* pcm configuration: identical with ALC880 */
a361d84b
KY
13077#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13078#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13079#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13080#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13081
13082/*
13083 * BIOS auto configuration
13084 */
13085static int alc268_parse_auto_config(struct hda_codec *codec)
13086{
13087 struct alc_spec *spec = codec->spec;
13088 int err;
13089 static hda_nid_t alc268_ignore[] = { 0 };
13090
13091 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13092 alc268_ignore);
13093 if (err < 0)
13094 return err;
7e0e44d4
TI
13095 if (!spec->autocfg.line_outs) {
13096 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13097 spec->multiout.max_channels = 2;
13098 spec->no_analog = 1;
13099 goto dig_only;
13100 }
a361d84b 13101 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13102 }
a361d84b
KY
13103 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13104 if (err < 0)
13105 return err;
05f5f477 13106 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13107 if (err < 0)
13108 return err;
13109
13110 spec->multiout.max_channels = 2;
13111
7e0e44d4 13112 dig_only:
a361d84b 13113 /* digital only support output */
7e0e44d4 13114 if (spec->autocfg.dig_outs) {
a361d84b 13115 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
13116 spec->dig_out_type = spec->autocfg.dig_out_type[0];
13117 }
603c4019 13118 if (spec->kctls.list)
d88897ea 13119 add_mixer(spec, spec->kctls.list);
a361d84b 13120
892981ff 13121 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13122 add_mixer(spec, alc268_beep_mixer);
aef9d318 13123
d88897ea 13124 add_verb(spec, alc268_volume_init_verbs);
5908589f 13125 spec->num_mux_defs = 2;
61b9b9b1 13126 spec->input_mux = &spec->private_imux[0];
a361d84b 13127
776e184e
TI
13128 err = alc_auto_add_mic_boost(codec);
13129 if (err < 0)
13130 return err;
13131
6227cdce 13132 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13133
a361d84b
KY
13134 return 1;
13135}
13136
a361d84b
KY
13137#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13138
13139/* init callback for auto-configuration model -- overriding the default init */
13140static void alc268_auto_init(struct hda_codec *codec)
13141{
f6c7e546 13142 struct alc_spec *spec = codec->spec;
a361d84b
KY
13143 alc268_auto_init_multi_out(codec);
13144 alc268_auto_init_hp_out(codec);
13145 alc268_auto_init_mono_speaker_out(codec);
13146 alc268_auto_init_analog_input(codec);
f6c7e546 13147 if (spec->unsol_event)
7fb0d78f 13148 alc_inithook(codec);
a361d84b
KY
13149}
13150
13151/*
13152 * configuration and preset
13153 */
13154static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13155 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13156 [ALC268_3ST] = "3stack",
983f8ae4 13157 [ALC268_TOSHIBA] = "toshiba",
d273809e 13158 [ALC268_ACER] = "acer",
c238b4f4 13159 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13160 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13161 [ALC268_DELL] = "dell",
f12462c5 13162 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13163#ifdef CONFIG_SND_DEBUG
13164 [ALC268_TEST] = "test",
13165#endif
a361d84b
KY
13166 [ALC268_AUTO] = "auto",
13167};
13168
13169static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13170 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13171 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13172 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13173 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13174 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13175 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13176 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13177 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13178 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13179 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13180 /* almost compatible with toshiba but with optional digital outs;
13181 * auto-probing seems working fine
13182 */
8871e5b9 13183 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13184 ALC268_AUTO),
a361d84b 13185 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13186 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13187 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13188 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13189 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13190 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13191 {}
13192};
13193
3abf2f36
TI
13194/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13195static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13196 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13197 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13198 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13199 ALC268_TOSHIBA),
13200 {}
13201};
13202
a361d84b 13203static struct alc_config_preset alc268_presets[] = {
eb5a6621 13204 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13205 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13206 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13207 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13208 alc267_quanta_il1_verbs },
13209 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13210 .dac_nids = alc268_dac_nids,
13211 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13212 .adc_nids = alc268_adc_nids_alt,
13213 .hp_nid = 0x03,
13214 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13215 .channel_mode = alc268_modes,
4f5d1706
TI
13216 .unsol_event = alc_sku_unsol_event,
13217 .setup = alc267_quanta_il1_setup,
13218 .init_hook = alc_inithook,
eb5a6621 13219 },
a361d84b 13220 [ALC268_3ST] = {
aef9d318
TI
13221 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13222 alc268_beep_mixer },
a361d84b
KY
13223 .init_verbs = { alc268_base_init_verbs },
13224 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13225 .dac_nids = alc268_dac_nids,
13226 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13227 .adc_nids = alc268_adc_nids_alt,
e1406348 13228 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13229 .hp_nid = 0x03,
13230 .dig_out_nid = ALC268_DIGOUT_NID,
13231 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13232 .channel_mode = alc268_modes,
13233 .input_mux = &alc268_capture_source,
13234 },
d1a991a6 13235 [ALC268_TOSHIBA] = {
42171c17 13236 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13237 alc268_beep_mixer },
d273809e
TI
13238 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13239 alc268_toshiba_verbs },
d1a991a6
KY
13240 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13241 .dac_nids = alc268_dac_nids,
13242 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13243 .adc_nids = alc268_adc_nids_alt,
e1406348 13244 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13245 .hp_nid = 0x03,
13246 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13247 .channel_mode = alc268_modes,
13248 .input_mux = &alc268_capture_source,
d273809e 13249 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13250 .setup = alc268_toshiba_setup,
13251 .init_hook = alc268_toshiba_automute,
d273809e
TI
13252 },
13253 [ALC268_ACER] = {
432fd133 13254 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13255 alc268_beep_mixer },
d273809e
TI
13256 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13257 alc268_acer_verbs },
13258 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13259 .dac_nids = alc268_dac_nids,
13260 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13261 .adc_nids = alc268_adc_nids_alt,
e1406348 13262 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13263 .hp_nid = 0x02,
13264 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13265 .channel_mode = alc268_modes,
0ccb541c 13266 .input_mux = &alc268_acer_capture_source,
d273809e 13267 .unsol_event = alc268_acer_unsol_event,
889c4395 13268 .init_hook = alc268_acer_init_hook,
d1a991a6 13269 },
c238b4f4
TI
13270 [ALC268_ACER_DMIC] = {
13271 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13272 alc268_beep_mixer },
13273 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13274 alc268_acer_verbs },
13275 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13276 .dac_nids = alc268_dac_nids,
13277 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13278 .adc_nids = alc268_adc_nids_alt,
13279 .capsrc_nids = alc268_capsrc_nids,
13280 .hp_nid = 0x02,
13281 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13282 .channel_mode = alc268_modes,
13283 .input_mux = &alc268_acer_dmic_capture_source,
13284 .unsol_event = alc268_acer_unsol_event,
13285 .init_hook = alc268_acer_init_hook,
13286 },
8ef355da
KY
13287 [ALC268_ACER_ASPIRE_ONE] = {
13288 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13289 alc268_beep_mixer,
fdbc6626 13290 alc268_capture_nosrc_mixer },
8ef355da
KY
13291 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13292 alc268_acer_aspire_one_verbs },
13293 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13294 .dac_nids = alc268_dac_nids,
13295 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13296 .adc_nids = alc268_adc_nids_alt,
13297 .capsrc_nids = alc268_capsrc_nids,
13298 .hp_nid = 0x03,
13299 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13300 .channel_mode = alc268_modes,
8ef355da 13301 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13302 .setup = alc268_acer_lc_setup,
8ef355da
KY
13303 .init_hook = alc268_acer_lc_init_hook,
13304 },
3866f0b0 13305 [ALC268_DELL] = {
fdbc6626
TI
13306 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13307 alc268_capture_nosrc_mixer },
3866f0b0
TI
13308 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13309 alc268_dell_verbs },
13310 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13311 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13312 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13313 .adc_nids = alc268_adc_nids_alt,
13314 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13315 .hp_nid = 0x02,
13316 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13317 .channel_mode = alc268_modes,
a9fd4f3f 13318 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13319 .setup = alc268_dell_setup,
13320 .init_hook = alc_inithook,
3866f0b0 13321 },
f12462c5 13322 [ALC268_ZEPTO] = {
aef9d318
TI
13323 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13324 alc268_beep_mixer },
f12462c5
MT
13325 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13326 alc268_toshiba_verbs },
13327 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13328 .dac_nids = alc268_dac_nids,
13329 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13330 .adc_nids = alc268_adc_nids_alt,
e1406348 13331 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13332 .hp_nid = 0x03,
13333 .dig_out_nid = ALC268_DIGOUT_NID,
13334 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13335 .channel_mode = alc268_modes,
13336 .input_mux = &alc268_capture_source,
4f5d1706
TI
13337 .setup = alc268_toshiba_setup,
13338 .init_hook = alc268_toshiba_automute,
f12462c5 13339 },
86c53bd2
JW
13340#ifdef CONFIG_SND_DEBUG
13341 [ALC268_TEST] = {
13342 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13343 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13344 alc268_volume_init_verbs },
13345 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13346 .dac_nids = alc268_dac_nids,
13347 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13348 .adc_nids = alc268_adc_nids_alt,
e1406348 13349 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13350 .hp_nid = 0x03,
13351 .dig_out_nid = ALC268_DIGOUT_NID,
13352 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13353 .channel_mode = alc268_modes,
13354 .input_mux = &alc268_capture_source,
13355 },
13356#endif
a361d84b
KY
13357};
13358
13359static int patch_alc268(struct hda_codec *codec)
13360{
13361 struct alc_spec *spec;
13362 int board_config;
22971e3a 13363 int i, has_beep, err;
a361d84b 13364
ef86f581 13365 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13366 if (spec == NULL)
13367 return -ENOMEM;
13368
13369 codec->spec = spec;
13370
13371 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13372 alc268_models,
13373 alc268_cfg_tbl);
13374
3abf2f36
TI
13375 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13376 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13377 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13378
a361d84b 13379 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13380 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13381 codec->chip_name);
a361d84b
KY
13382 board_config = ALC268_AUTO;
13383 }
13384
13385 if (board_config == ALC268_AUTO) {
13386 /* automatic parse from the BIOS config */
13387 err = alc268_parse_auto_config(codec);
13388 if (err < 0) {
13389 alc_free(codec);
13390 return err;
13391 } else if (!err) {
13392 printk(KERN_INFO
13393 "hda_codec: Cannot set up configuration "
13394 "from BIOS. Using base mode...\n");
13395 board_config = ALC268_3ST;
13396 }
13397 }
13398
13399 if (board_config != ALC268_AUTO)
e9c364c0 13400 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13401
a361d84b
KY
13402 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13403 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13404 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13405
a361d84b
KY
13406 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13407
22971e3a
TI
13408 has_beep = 0;
13409 for (i = 0; i < spec->num_mixers; i++) {
13410 if (spec->mixers[i] == alc268_beep_mixer) {
13411 has_beep = 1;
13412 break;
13413 }
13414 }
13415
13416 if (has_beep) {
13417 err = snd_hda_attach_beep_device(codec, 0x1);
13418 if (err < 0) {
13419 alc_free(codec);
13420 return err;
13421 }
13422 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13423 /* override the amp caps for beep generator */
13424 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13425 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13426 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13427 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13428 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13429 }
aef9d318 13430
7e0e44d4 13431 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13432 /* check whether NID 0x07 is valid */
13433 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13434 int i;
3866f0b0 13435
defb5ab2 13436 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13437 /* get type */
a22d543a 13438 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13439 if (spec->auto_mic ||
13440 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13441 spec->adc_nids = alc268_adc_nids_alt;
13442 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13443 if (spec->auto_mic)
13444 fixup_automic_adc(codec);
fdbc6626
TI
13445 if (spec->auto_mic || spec->input_mux->num_items == 1)
13446 add_mixer(spec, alc268_capture_nosrc_mixer);
13447 else
13448 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13449 } else {
13450 spec->adc_nids = alc268_adc_nids;
13451 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13452 add_mixer(spec, alc268_capture_mixer);
a361d84b 13453 }
85860c06
TI
13454 /* set default input source */
13455 for (i = 0; i < spec->num_adc_nids; i++)
13456 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13457 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13458 i < spec->num_mux_defs ?
13459 spec->input_mux[i].items[0].index :
85860c06 13460 spec->input_mux->items[0].index);
a361d84b 13461 }
2134ea4f
TI
13462
13463 spec->vmaster_nid = 0x02;
13464
a361d84b
KY
13465 codec->patch_ops = alc_patch_ops;
13466 if (board_config == ALC268_AUTO)
13467 spec->init_hook = alc268_auto_init;
ea1fb29a 13468
a361d84b
KY
13469 return 0;
13470}
13471
f6a92248
KY
13472/*
13473 * ALC269 channel source setting (2 channel)
13474 */
13475#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13476
13477#define alc269_dac_nids alc260_dac_nids
13478
13479static hda_nid_t alc269_adc_nids[1] = {
13480 /* ADC1 */
f53281e6
KY
13481 0x08,
13482};
13483
e01bf509
TI
13484static hda_nid_t alc269_capsrc_nids[1] = {
13485 0x23,
13486};
13487
84898e87
KY
13488static hda_nid_t alc269vb_adc_nids[1] = {
13489 /* ADC1 */
13490 0x09,
13491};
13492
13493static hda_nid_t alc269vb_capsrc_nids[1] = {
13494 0x22,
13495};
13496
6694635d
TI
13497static hda_nid_t alc269_adc_candidates[] = {
13498 0x08, 0x09, 0x07,
13499};
e01bf509 13500
f6a92248
KY
13501#define alc269_modes alc260_modes
13502#define alc269_capture_source alc880_lg_lw_capture_source
13503
13504static struct snd_kcontrol_new alc269_base_mixer[] = {
13505 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13506 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13511 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13512 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13513 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13514 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13515 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13516 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13517 { } /* end */
13518};
13519
60db6b53
KY
13520static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13521 /* output mixer control */
13522 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13523 {
13524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13525 .name = "Master Playback Switch",
5e26dfd0 13526 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13527 .info = snd_hda_mixer_amp_switch_info,
13528 .get = snd_hda_mixer_amp_switch_get,
13529 .put = alc268_acer_master_sw_put,
13530 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13531 },
13532 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13534 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13535 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13536 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13537 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13538 { }
13539};
13540
64154835
TV
13541static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13542 /* output mixer control */
13543 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13544 {
13545 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13546 .name = "Master Playback Switch",
5e26dfd0 13547 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13548 .info = snd_hda_mixer_amp_switch_info,
13549 .get = snd_hda_mixer_amp_switch_get,
13550 .put = alc268_acer_master_sw_put,
13551 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13552 },
13553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13555 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13556 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13557 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13558 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13559 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13560 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13561 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13562 { }
13563};
13564
84898e87 13565static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13566 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13567 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13569 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13570 { } /* end */
13571};
13572
84898e87
KY
13573static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13574 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13577 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13578 { } /* end */
13579};
13580
f53281e6 13581/* capture mixer elements */
84898e87
KY
13582static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13583 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13584 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13585 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13586 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13587 { } /* end */
13588};
13589
13590static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13591 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13592 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13593 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13594 { } /* end */
13595};
13596
84898e87
KY
13597static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13598 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13599 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13600 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13601 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13602 { } /* end */
13603};
13604
13605static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13606 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13607 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13608 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13609 { } /* end */
13610};
13611
26f5df26 13612/* FSC amilo */
84898e87 13613#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13614
60db6b53
KY
13615static struct hda_verb alc269_quanta_fl1_verbs[] = {
13616 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13617 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13618 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13619 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13620 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13621 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13622 { }
13623};
f6a92248 13624
64154835
TV
13625static struct hda_verb alc269_lifebook_verbs[] = {
13626 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13627 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13628 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13630 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13633 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13634 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13635 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13636 { }
13637};
13638
60db6b53
KY
13639/* toggle speaker-output according to the hp-jack state */
13640static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13641{
13642 unsigned int present;
13643 unsigned char bits;
f6a92248 13644
864f92be 13645 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13646 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13647 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13648 HDA_AMP_MUTE, bits);
60db6b53 13649 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13650 HDA_AMP_MUTE, bits);
f6a92248 13651
60db6b53
KY
13652 snd_hda_codec_write(codec, 0x20, 0,
13653 AC_VERB_SET_COEF_INDEX, 0x0c);
13654 snd_hda_codec_write(codec, 0x20, 0,
13655 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13656
60db6b53
KY
13657 snd_hda_codec_write(codec, 0x20, 0,
13658 AC_VERB_SET_COEF_INDEX, 0x0c);
13659 snd_hda_codec_write(codec, 0x20, 0,
13660 AC_VERB_SET_PROC_COEF, 0x480);
13661}
f6a92248 13662
64154835
TV
13663/* toggle speaker-output according to the hp-jacks state */
13664static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13665{
13666 unsigned int present;
13667 unsigned char bits;
13668
13669 /* Check laptop headphone socket */
864f92be 13670 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13671
13672 /* Check port replicator headphone socket */
864f92be 13673 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13674
5dbd5ec6 13675 bits = present ? HDA_AMP_MUTE : 0;
64154835 13676 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13677 HDA_AMP_MUTE, bits);
64154835 13678 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13679 HDA_AMP_MUTE, bits);
64154835
TV
13680
13681 snd_hda_codec_write(codec, 0x20, 0,
13682 AC_VERB_SET_COEF_INDEX, 0x0c);
13683 snd_hda_codec_write(codec, 0x20, 0,
13684 AC_VERB_SET_PROC_COEF, 0x680);
13685
13686 snd_hda_codec_write(codec, 0x20, 0,
13687 AC_VERB_SET_COEF_INDEX, 0x0c);
13688 snd_hda_codec_write(codec, 0x20, 0,
13689 AC_VERB_SET_PROC_COEF, 0x480);
13690}
13691
64154835
TV
13692static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13693{
13694 unsigned int present_laptop;
13695 unsigned int present_dock;
13696
864f92be
WF
13697 present_laptop = snd_hda_jack_detect(codec, 0x18);
13698 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13699
13700 /* Laptop mic port overrides dock mic port, design decision */
13701 if (present_dock)
13702 snd_hda_codec_write(codec, 0x23, 0,
13703 AC_VERB_SET_CONNECT_SEL, 0x3);
13704 if (present_laptop)
13705 snd_hda_codec_write(codec, 0x23, 0,
13706 AC_VERB_SET_CONNECT_SEL, 0x0);
13707 if (!present_dock && !present_laptop)
13708 snd_hda_codec_write(codec, 0x23, 0,
13709 AC_VERB_SET_CONNECT_SEL, 0x1);
13710}
13711
60db6b53
KY
13712static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13713 unsigned int res)
13714{
4f5d1706
TI
13715 switch (res >> 26) {
13716 case ALC880_HP_EVENT:
60db6b53 13717 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13718 break;
13719 case ALC880_MIC_EVENT:
13720 alc_mic_automute(codec);
13721 break;
13722 }
60db6b53 13723}
f6a92248 13724
64154835
TV
13725static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13726 unsigned int res)
13727{
13728 if ((res >> 26) == ALC880_HP_EVENT)
13729 alc269_lifebook_speaker_automute(codec);
13730 if ((res >> 26) == ALC880_MIC_EVENT)
13731 alc269_lifebook_mic_autoswitch(codec);
13732}
13733
4f5d1706
TI
13734static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13735{
13736 struct alc_spec *spec = codec->spec;
20645d70
TI
13737 spec->autocfg.hp_pins[0] = 0x15;
13738 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13739 spec->ext_mic.pin = 0x18;
13740 spec->ext_mic.mux_idx = 0;
13741 spec->int_mic.pin = 0x19;
13742 spec->int_mic.mux_idx = 1;
13743 spec->auto_mic = 1;
13744}
13745
60db6b53
KY
13746static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13747{
13748 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13749 alc_mic_automute(codec);
60db6b53 13750}
f6a92248 13751
64154835
TV
13752static void alc269_lifebook_init_hook(struct hda_codec *codec)
13753{
13754 alc269_lifebook_speaker_automute(codec);
13755 alc269_lifebook_mic_autoswitch(codec);
13756}
13757
84898e87 13758static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
13759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13760 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13761 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13762 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13764 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13765 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13766 {}
13767};
13768
84898e87 13769static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
13770 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13771 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13772 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13773 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13774 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13775 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13776 {}
13777};
13778
84898e87
KY
13779static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13780 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13781 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13782 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13783 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13784 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13785 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13786 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13787 {}
13788};
13789
13790static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13791 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13792 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13793 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13795 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13797 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13798 {}
13799};
13800
f53281e6
KY
13801/* toggle speaker-output according to the hp-jack state */
13802static void alc269_speaker_automute(struct hda_codec *codec)
13803{
ebb83eeb
KY
13804 struct alc_spec *spec = codec->spec;
13805 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 13806 unsigned int present;
60db6b53 13807 unsigned char bits;
f53281e6 13808
ebb83eeb 13809 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 13810 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 13811 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13812 HDA_AMP_MUTE, bits);
f53281e6 13813 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13814 HDA_AMP_MUTE, bits);
f53281e6
KY
13815}
13816
f53281e6 13817/* unsolicited event for HP jack sensing */
84898e87 13818static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 13819 unsigned int res)
f53281e6 13820{
4f5d1706
TI
13821 switch (res >> 26) {
13822 case ALC880_HP_EVENT:
f53281e6 13823 alc269_speaker_automute(codec);
4f5d1706
TI
13824 break;
13825 case ALC880_MIC_EVENT:
13826 alc_mic_automute(codec);
13827 break;
13828 }
f53281e6
KY
13829}
13830
84898e87 13831static void alc269_laptop_dmic_setup(struct hda_codec *codec)
f53281e6 13832{
4f5d1706 13833 struct alc_spec *spec = codec->spec;
20645d70
TI
13834 spec->autocfg.hp_pins[0] = 0x15;
13835 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13836 spec->ext_mic.pin = 0x18;
13837 spec->ext_mic.mux_idx = 0;
13838 spec->int_mic.pin = 0x12;
13839 spec->int_mic.mux_idx = 5;
13840 spec->auto_mic = 1;
f53281e6
KY
13841}
13842
84898e87
KY
13843static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13844{
13845 struct alc_spec *spec = codec->spec;
20645d70
TI
13846 spec->autocfg.hp_pins[0] = 0x15;
13847 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
13848 spec->ext_mic.pin = 0x18;
13849 spec->ext_mic.mux_idx = 0;
13850 spec->int_mic.pin = 0x12;
13851 spec->int_mic.mux_idx = 6;
13852 spec->auto_mic = 1;
13853}
13854
13855static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 13856{
4f5d1706 13857 struct alc_spec *spec = codec->spec;
20645d70
TI
13858 spec->autocfg.hp_pins[0] = 0x15;
13859 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13860 spec->ext_mic.pin = 0x18;
13861 spec->ext_mic.mux_idx = 0;
13862 spec->int_mic.pin = 0x19;
13863 spec->int_mic.mux_idx = 1;
13864 spec->auto_mic = 1;
f53281e6
KY
13865}
13866
84898e87 13867static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
13868{
13869 alc269_speaker_automute(codec);
4f5d1706 13870 alc_mic_automute(codec);
f53281e6
KY
13871}
13872
60db6b53
KY
13873/*
13874 * generic initialization of ADC, input mixers and output mixers
13875 */
13876static struct hda_verb alc269_init_verbs[] = {
13877 /*
13878 * Unmute ADC0 and set the default input to mic-in
13879 */
84898e87 13880 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
13881
13882 /*
84898e87 13883 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
13884 */
13885 /* set vol=0 to output mixers */
13886 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13887 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13888
13889 /* set up input amps for analog loopback */
13890 /* Amp Indices: DAC = 0, mixer = 1 */
13891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13893 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13894 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13895 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13897
13898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13901 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13905
13906 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 13908
84898e87
KY
13909 /* FIXME: use Mux-type input source selection */
13910 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13911 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13912 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 13913
84898e87
KY
13914 /* set EAPD */
13915 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13916 { }
13917};
13918
13919static struct hda_verb alc269vb_init_verbs[] = {
13920 /*
13921 * Unmute ADC0 and set the default input to mic-in
13922 */
13923 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13924
13925 /*
13926 * Set up output mixers (0x02 - 0x03)
13927 */
13928 /* set vol=0 to output mixers */
13929 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13930 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13931
13932 /* set up input amps for analog loopback */
13933 /* Amp Indices: DAC = 0, mixer = 1 */
13934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13936 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13937 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13938 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13939 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13940
13941 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13942 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13943 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13946 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13947 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13948
13949 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13950 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13951
13952 /* FIXME: use Mux-type input source selection */
60db6b53
KY
13953 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13954 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 13955 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
13956
13957 /* set EAPD */
13958 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
13959 { }
13960};
13961
9d0b71b1
TI
13962#define alc269_auto_create_multi_out_ctls \
13963 alc268_auto_create_multi_out_ctls
05f5f477
TI
13964#define alc269_auto_create_input_ctls \
13965 alc268_auto_create_input_ctls
f6a92248
KY
13966
13967#ifdef CONFIG_SND_HDA_POWER_SAVE
13968#define alc269_loopbacks alc880_loopbacks
13969#endif
13970
def319f9 13971/* pcm configuration: identical with ALC880 */
f6a92248
KY
13972#define alc269_pcm_analog_playback alc880_pcm_analog_playback
13973#define alc269_pcm_analog_capture alc880_pcm_analog_capture
13974#define alc269_pcm_digital_playback alc880_pcm_digital_playback
13975#define alc269_pcm_digital_capture alc880_pcm_digital_capture
13976
f03d3115
TI
13977static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13978 .substreams = 1,
13979 .channels_min = 2,
13980 .channels_max = 8,
13981 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13982 /* NID is set in alc_build_pcms */
13983 .ops = {
13984 .open = alc880_playback_pcm_open,
13985 .prepare = alc880_playback_pcm_prepare,
13986 .cleanup = alc880_playback_pcm_cleanup
13987 },
13988};
13989
13990static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13991 .substreams = 1,
13992 .channels_min = 2,
13993 .channels_max = 2,
13994 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13995 /* NID is set in alc_build_pcms */
13996};
13997
ad35879a
TI
13998#ifdef CONFIG_SND_HDA_POWER_SAVE
13999static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14000{
14001 switch (codec->subsystem_id) {
14002 case 0x103c1586:
14003 return 1;
14004 }
14005 return 0;
14006}
14007
14008static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14009{
14010 /* update mute-LED according to the speaker mute state */
14011 if (nid == 0x01 || nid == 0x14) {
14012 int pinval;
14013 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14014 HDA_AMP_MUTE)
14015 pinval = 0x24;
14016 else
14017 pinval = 0x20;
14018 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14019 snd_hda_codec_update_cache(codec, 0x19, 0,
14020 AC_VERB_SET_PIN_WIDGET_CONTROL,
14021 pinval);
ad35879a
TI
14022 }
14023 return alc_check_power_status(codec, nid);
14024}
14025#endif /* CONFIG_SND_HDA_POWER_SAVE */
14026
f6a92248
KY
14027/*
14028 * BIOS auto configuration
14029 */
14030static int alc269_parse_auto_config(struct hda_codec *codec)
14031{
14032 struct alc_spec *spec = codec->spec;
cfb9fb55 14033 int err;
f6a92248
KY
14034 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14035
14036 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14037 alc269_ignore);
14038 if (err < 0)
14039 return err;
14040
14041 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14042 if (err < 0)
14043 return err;
05f5f477 14044 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14045 if (err < 0)
14046 return err;
14047
14048 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14049
0852d7a6 14050 if (spec->autocfg.dig_outs)
f6a92248
KY
14051 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
14052
603c4019 14053 if (spec->kctls.list)
d88897ea 14054 add_mixer(spec, spec->kctls.list);
f6a92248 14055
84898e87
KY
14056 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14057 add_verb(spec, alc269vb_init_verbs);
6227cdce 14058 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14059 } else {
14060 add_verb(spec, alc269_init_verbs);
6227cdce 14061 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14062 }
14063
f6a92248 14064 spec->num_mux_defs = 1;
61b9b9b1 14065 spec->input_mux = &spec->private_imux[0];
6694635d
TI
14066 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14067 sizeof(alc269_adc_candidates));
14068
e01bf509 14069 /* set default input source */
6694635d 14070 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14071 0, AC_VERB_SET_CONNECT_SEL,
14072 spec->input_mux->items[0].index);
f6a92248
KY
14073
14074 err = alc_auto_add_mic_boost(codec);
14075 if (err < 0)
14076 return err;
14077
7e0e44d4 14078 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14079 set_capture_mixer(codec);
f53281e6 14080
f6a92248
KY
14081 return 1;
14082}
14083
e9af4f36
TI
14084#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14085#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14086#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14087
14088
14089/* init callback for auto-configuration model -- overriding the default init */
14090static void alc269_auto_init(struct hda_codec *codec)
14091{
f6c7e546 14092 struct alc_spec *spec = codec->spec;
f6a92248
KY
14093 alc269_auto_init_multi_out(codec);
14094 alc269_auto_init_hp_out(codec);
14095 alc269_auto_init_analog_input(codec);
f6c7e546 14096 if (spec->unsol_event)
7fb0d78f 14097 alc_inithook(codec);
f6a92248
KY
14098}
14099
14100/*
14101 * configuration and preset
14102 */
14103static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14104 [ALC269_BASIC] = "basic",
2922c9af 14105 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14106 [ALC269_AMIC] = "laptop-amic",
14107 [ALC269_DMIC] = "laptop-dmic",
64154835 14108 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14109 [ALC269_LIFEBOOK] = "lifebook",
14110 [ALC269_AUTO] = "auto",
f6a92248
KY
14111};
14112
14113static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14114 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14115 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14116 ALC269_AMIC),
14117 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14118 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14119 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14120 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14121 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14122 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14123 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14124 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14125 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14126 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14127 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14128 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14129 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14130 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14131 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14132 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14133 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14134 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14135 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14136 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14137 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14138 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14139 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14140 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14141 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14142 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14143 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14144 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14145 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14146 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14147 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14148 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14149 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14150 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14151 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14152 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14153 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14154 ALC269_DMIC),
60db6b53 14155 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14156 ALC269_DMIC),
14157 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14158 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
61c2d2b5 14159 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
64154835 14160 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14161 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14162 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14163 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14164 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14165 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14166 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14167 {}
14168};
14169
14170static struct alc_config_preset alc269_presets[] = {
14171 [ALC269_BASIC] = {
f9e336f6 14172 .mixers = { alc269_base_mixer },
f6a92248
KY
14173 .init_verbs = { alc269_init_verbs },
14174 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14175 .dac_nids = alc269_dac_nids,
14176 .hp_nid = 0x03,
14177 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14178 .channel_mode = alc269_modes,
14179 .input_mux = &alc269_capture_source,
14180 },
60db6b53
KY
14181 [ALC269_QUANTA_FL1] = {
14182 .mixers = { alc269_quanta_fl1_mixer },
14183 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14184 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14185 .dac_nids = alc269_dac_nids,
14186 .hp_nid = 0x03,
14187 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14188 .channel_mode = alc269_modes,
14189 .input_mux = &alc269_capture_source,
14190 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14191 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14192 .init_hook = alc269_quanta_fl1_init_hook,
14193 },
84898e87
KY
14194 [ALC269_AMIC] = {
14195 .mixers = { alc269_laptop_mixer },
14196 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14197 .init_verbs = { alc269_init_verbs,
84898e87 14198 alc269_laptop_amic_init_verbs },
f53281e6
KY
14199 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14200 .dac_nids = alc269_dac_nids,
14201 .hp_nid = 0x03,
14202 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14203 .channel_mode = alc269_modes,
84898e87
KY
14204 .unsol_event = alc269_laptop_unsol_event,
14205 .setup = alc269_laptop_amic_setup,
14206 .init_hook = alc269_laptop_inithook,
f53281e6 14207 },
84898e87
KY
14208 [ALC269_DMIC] = {
14209 .mixers = { alc269_laptop_mixer },
14210 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14211 .init_verbs = { alc269_init_verbs,
84898e87
KY
14212 alc269_laptop_dmic_init_verbs },
14213 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14214 .dac_nids = alc269_dac_nids,
14215 .hp_nid = 0x03,
14216 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14217 .channel_mode = alc269_modes,
14218 .unsol_event = alc269_laptop_unsol_event,
14219 .setup = alc269_laptop_dmic_setup,
14220 .init_hook = alc269_laptop_inithook,
14221 },
14222 [ALC269VB_AMIC] = {
14223 .mixers = { alc269vb_laptop_mixer },
14224 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14225 .init_verbs = { alc269vb_init_verbs,
14226 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14227 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14228 .dac_nids = alc269_dac_nids,
14229 .hp_nid = 0x03,
14230 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14231 .channel_mode = alc269_modes,
84898e87
KY
14232 .unsol_event = alc269_laptop_unsol_event,
14233 .setup = alc269_laptop_amic_setup,
14234 .init_hook = alc269_laptop_inithook,
14235 },
14236 [ALC269VB_DMIC] = {
14237 .mixers = { alc269vb_laptop_mixer },
14238 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14239 .init_verbs = { alc269vb_init_verbs,
14240 alc269vb_laptop_dmic_init_verbs },
14241 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14242 .dac_nids = alc269_dac_nids,
14243 .hp_nid = 0x03,
14244 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14245 .channel_mode = alc269_modes,
14246 .unsol_event = alc269_laptop_unsol_event,
14247 .setup = alc269vb_laptop_dmic_setup,
14248 .init_hook = alc269_laptop_inithook,
f53281e6 14249 },
26f5df26 14250 [ALC269_FUJITSU] = {
45bdd1c1 14251 .mixers = { alc269_fujitsu_mixer },
84898e87 14252 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14253 .init_verbs = { alc269_init_verbs,
84898e87 14254 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14255 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14256 .dac_nids = alc269_dac_nids,
14257 .hp_nid = 0x03,
14258 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14259 .channel_mode = alc269_modes,
84898e87
KY
14260 .unsol_event = alc269_laptop_unsol_event,
14261 .setup = alc269_laptop_dmic_setup,
14262 .init_hook = alc269_laptop_inithook,
26f5df26 14263 },
64154835
TV
14264 [ALC269_LIFEBOOK] = {
14265 .mixers = { alc269_lifebook_mixer },
14266 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14267 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14268 .dac_nids = alc269_dac_nids,
14269 .hp_nid = 0x03,
14270 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14271 .channel_mode = alc269_modes,
14272 .input_mux = &alc269_capture_source,
14273 .unsol_event = alc269_lifebook_unsol_event,
14274 .init_hook = alc269_lifebook_init_hook,
14275 },
f6a92248
KY
14276};
14277
14278static int patch_alc269(struct hda_codec *codec)
14279{
14280 struct alc_spec *spec;
14281 int board_config;
14282 int err;
84898e87 14283 int is_alc269vb = 0;
f6a92248
KY
14284
14285 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14286 if (spec == NULL)
14287 return -ENOMEM;
14288
14289 codec->spec = spec;
14290
da00c244
KY
14291 alc_auto_parse_customize_define(codec);
14292
274693f3 14293 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14294 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14295 spec->cdefine.platform_type == 1)
14296 alc_codec_rename(codec, "ALC271X");
14297 else
14298 alc_codec_rename(codec, "ALC259");
84898e87 14299 is_alc269vb = 1;
c027ddcd
KY
14300 } else
14301 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14302
f6a92248
KY
14303 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14304 alc269_models,
14305 alc269_cfg_tbl);
14306
14307 if (board_config < 0) {
9a11f1aa
TI
14308 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14309 codec->chip_name);
f6a92248
KY
14310 board_config = ALC269_AUTO;
14311 }
14312
14313 if (board_config == ALC269_AUTO) {
14314 /* automatic parse from the BIOS config */
14315 err = alc269_parse_auto_config(codec);
14316 if (err < 0) {
14317 alc_free(codec);
14318 return err;
14319 } else if (!err) {
14320 printk(KERN_INFO
14321 "hda_codec: Cannot set up configuration "
14322 "from BIOS. Using base mode...\n");
14323 board_config = ALC269_BASIC;
14324 }
14325 }
14326
680cd536
KK
14327 err = snd_hda_attach_beep_device(codec, 0x1);
14328 if (err < 0) {
14329 alc_free(codec);
14330 return err;
14331 }
14332
f6a92248 14333 if (board_config != ALC269_AUTO)
e9c364c0 14334 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14335
84898e87 14336 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14337 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14338 * fix the sample rate of analog I/O to 44.1kHz
14339 */
14340 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14341 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14342 } else {
14343 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14344 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14345 }
f6a92248
KY
14346 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14347 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14348
6694635d
TI
14349 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14350 if (!is_alc269vb) {
14351 spec->adc_nids = alc269_adc_nids;
14352 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14353 spec->capsrc_nids = alc269_capsrc_nids;
14354 } else {
14355 spec->adc_nids = alc269vb_adc_nids;
14356 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14357 spec->capsrc_nids = alc269vb_capsrc_nids;
14358 }
84898e87
KY
14359 }
14360
f9e336f6 14361 if (!spec->cap_mixer)
b59bdf3b 14362 set_capture_mixer(codec);
da00c244
KY
14363 if (spec->cdefine.enable_pcbeep)
14364 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14365
100d5eb3
TI
14366 spec->vmaster_nid = 0x02;
14367
f6a92248
KY
14368 codec->patch_ops = alc_patch_ops;
14369 if (board_config == ALC269_AUTO)
14370 spec->init_hook = alc269_auto_init;
14371#ifdef CONFIG_SND_HDA_POWER_SAVE
14372 if (!spec->loopback.amplist)
14373 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14374 if (alc269_mic2_for_mute_led(codec))
14375 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14376#endif
14377
14378 return 0;
14379}
14380
df694daa
KY
14381/*
14382 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14383 */
14384
14385/*
14386 * set the path ways for 2 channel output
14387 * need to set the codec line out and mic 1 pin widgets to inputs
14388 */
14389static struct hda_verb alc861_threestack_ch2_init[] = {
14390 /* set pin widget 1Ah (line in) for input */
14391 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14392 /* set pin widget 18h (mic1/2) for input, for mic also enable
14393 * the vref
14394 */
df694daa
KY
14395 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14396
9c7f852e
TI
14397 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14398#if 0
14399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14400 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14401#endif
df694daa
KY
14402 { } /* end */
14403};
14404/*
14405 * 6ch mode
14406 * need to set the codec line out and mic 1 pin widgets to outputs
14407 */
14408static struct hda_verb alc861_threestack_ch6_init[] = {
14409 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14410 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14411 /* set pin widget 18h (mic1) for output (CLFE)*/
14412 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14413
14414 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14415 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14416
9c7f852e
TI
14417 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14418#if 0
14419 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14420 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14421#endif
df694daa
KY
14422 { } /* end */
14423};
14424
14425static struct hda_channel_mode alc861_threestack_modes[2] = {
14426 { 2, alc861_threestack_ch2_init },
14427 { 6, alc861_threestack_ch6_init },
14428};
22309c3e
TI
14429/* Set mic1 as input and unmute the mixer */
14430static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14431 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14432 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14433 { } /* end */
14434};
14435/* Set mic1 as output and mute mixer */
14436static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14437 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14438 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14439 { } /* end */
14440};
14441
14442static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14443 { 2, alc861_uniwill_m31_ch2_init },
14444 { 4, alc861_uniwill_m31_ch4_init },
14445};
df694daa 14446
7cdbff94
MD
14447/* Set mic1 and line-in as input and unmute the mixer */
14448static struct hda_verb alc861_asus_ch2_init[] = {
14449 /* set pin widget 1Ah (line in) for input */
14450 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14451 /* set pin widget 18h (mic1/2) for input, for mic also enable
14452 * the vref
14453 */
7cdbff94
MD
14454 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14455
14456 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14457#if 0
14458 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14459 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14460#endif
14461 { } /* end */
14462};
14463/* Set mic1 nad line-in as output and mute mixer */
14464static struct hda_verb alc861_asus_ch6_init[] = {
14465 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14466 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14467 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14468 /* set pin widget 18h (mic1) for output (CLFE)*/
14469 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14470 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14471 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14472 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14473
14474 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14475#if 0
14476 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14477 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14478#endif
14479 { } /* end */
14480};
14481
14482static struct hda_channel_mode alc861_asus_modes[2] = {
14483 { 2, alc861_asus_ch2_init },
14484 { 6, alc861_asus_ch6_init },
14485};
14486
df694daa
KY
14487/* patch-ALC861 */
14488
14489static struct snd_kcontrol_new alc861_base_mixer[] = {
14490 /* output mixer control */
14491 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14492 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14493 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14494 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14495 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14496
14497 /*Input mixer control */
14498 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14499 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14500 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14501 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14502 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14503 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14505 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14506 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14508
df694daa
KY
14509 { } /* end */
14510};
14511
14512static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14513 /* output mixer control */
14514 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14515 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14516 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14517 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14518 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14519
14520 /* Input mixer control */
14521 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14522 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14523 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14524 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14525 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14526 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14527 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14528 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14529 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14531
df694daa
KY
14532 {
14533 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14534 .name = "Channel Mode",
14535 .info = alc_ch_mode_info,
14536 .get = alc_ch_mode_get,
14537 .put = alc_ch_mode_put,
14538 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14539 },
14540 { } /* end */
a53d1aec
TD
14541};
14542
d1d985f0 14543static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14544 /* output mixer control */
14545 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14547 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14548
a53d1aec 14549 { } /* end */
f12ab1e0 14550};
a53d1aec 14551
22309c3e
TI
14552static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14553 /* output mixer control */
14554 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14555 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14556 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14557 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14558 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14559
14560 /* Input mixer control */
14561 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14562 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14563 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14564 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14565 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14566 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14567 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14568 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14569 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14570 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14571
22309c3e
TI
14572 {
14573 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14574 .name = "Channel Mode",
14575 .info = alc_ch_mode_info,
14576 .get = alc_ch_mode_get,
14577 .put = alc_ch_mode_put,
14578 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14579 },
14580 { } /* end */
f12ab1e0 14581};
7cdbff94
MD
14582
14583static struct snd_kcontrol_new alc861_asus_mixer[] = {
14584 /* output mixer control */
14585 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14586 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14587 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14588 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14589 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14590
14591 /* Input mixer control */
14592 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14593 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14594 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14595 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14596 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14597 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14599 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14601 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14602
7cdbff94
MD
14603 {
14604 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14605 .name = "Channel Mode",
14606 .info = alc_ch_mode_info,
14607 .get = alc_ch_mode_get,
14608 .put = alc_ch_mode_put,
14609 .private_value = ARRAY_SIZE(alc861_asus_modes),
14610 },
14611 { }
56bb0cab
TI
14612};
14613
14614/* additional mixer */
d1d985f0 14615static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14616 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14617 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14618 { }
14619};
7cdbff94 14620
df694daa
KY
14621/*
14622 * generic initialization of ADC, input mixers and output mixers
14623 */
14624static struct hda_verb alc861_base_init_verbs[] = {
14625 /*
14626 * Unmute ADC0 and set the default input to mic-in
14627 */
14628 /* port-A for surround (rear panel) */
14629 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14630 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14631 /* port-B for mic-in (rear panel) with vref */
14632 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14633 /* port-C for line-in (rear panel) */
14634 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14635 /* port-D for Front */
14636 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14637 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14638 /* port-E for HP out (front panel) */
14639 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14640 /* route front PCM to HP */
9dece1d7 14641 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14642 /* port-F for mic-in (front panel) with vref */
14643 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14644 /* port-G for CLFE (rear panel) */
14645 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14646 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14647 /* port-H for side (rear panel) */
14648 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14649 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14650 /* CD-in */
14651 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14652 /* route front mic to ADC1*/
14653 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14654 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14655
df694daa
KY
14656 /* Unmute DAC0~3 & spdif out*/
14657 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14658 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14659 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14660 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14662
df694daa
KY
14663 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14664 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14665 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14666 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14667 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14668
df694daa
KY
14669 /* Unmute Stereo Mixer 15 */
14670 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14674
14675 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14676 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14677 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14678 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14679 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14681 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14682 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14683 /* hp used DAC 3 (Front) */
14684 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14685 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14686
14687 { }
14688};
14689
14690static struct hda_verb alc861_threestack_init_verbs[] = {
14691 /*
14692 * Unmute ADC0 and set the default input to mic-in
14693 */
14694 /* port-A for surround (rear panel) */
14695 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14696 /* port-B for mic-in (rear panel) with vref */
14697 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14698 /* port-C for line-in (rear panel) */
14699 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14700 /* port-D for Front */
14701 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14702 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14703 /* port-E for HP out (front panel) */
14704 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14705 /* route front PCM to HP */
9dece1d7 14706 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14707 /* port-F for mic-in (front panel) with vref */
14708 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14709 /* port-G for CLFE (rear panel) */
14710 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14711 /* port-H for side (rear panel) */
14712 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14713 /* CD-in */
14714 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14715 /* route front mic to ADC1*/
14716 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14717 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14718 /* Unmute DAC0~3 & spdif out*/
14719 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14720 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14721 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14722 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14723 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14724
df694daa
KY
14725 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14726 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14727 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14728 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14729 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14730
df694daa
KY
14731 /* Unmute Stereo Mixer 15 */
14732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14736
14737 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14739 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14740 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14744 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14745 /* hp used DAC 3 (Front) */
14746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14748 { }
14749};
22309c3e
TI
14750
14751static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14752 /*
14753 * Unmute ADC0 and set the default input to mic-in
14754 */
14755 /* port-A for surround (rear panel) */
14756 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14757 /* port-B for mic-in (rear panel) with vref */
14758 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14759 /* port-C for line-in (rear panel) */
14760 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14761 /* port-D for Front */
14762 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14763 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14764 /* port-E for HP out (front panel) */
f12ab1e0
TI
14765 /* this has to be set to VREF80 */
14766 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 14767 /* route front PCM to HP */
9dece1d7 14768 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
14769 /* port-F for mic-in (front panel) with vref */
14770 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14771 /* port-G for CLFE (rear panel) */
14772 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14773 /* port-H for side (rear panel) */
14774 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14775 /* CD-in */
14776 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14777 /* route front mic to ADC1*/
14778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14779 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14780 /* Unmute DAC0~3 & spdif out*/
14781 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14782 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14783 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14784 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14785 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14786
22309c3e
TI
14787 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14788 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14789 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14790 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14791 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14792
22309c3e
TI
14793 /* Unmute Stereo Mixer 15 */
14794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
14798
14799 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14801 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14802 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14803 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14806 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14807 /* hp used DAC 3 (Front) */
14808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
14809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14810 { }
14811};
14812
7cdbff94
MD
14813static struct hda_verb alc861_asus_init_verbs[] = {
14814 /*
14815 * Unmute ADC0 and set the default input to mic-in
14816 */
f12ab1e0
TI
14817 /* port-A for surround (rear panel)
14818 * according to codec#0 this is the HP jack
14819 */
7cdbff94
MD
14820 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14821 /* route front PCM to HP */
14822 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14823 /* port-B for mic-in (rear panel) with vref */
14824 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14825 /* port-C for line-in (rear panel) */
14826 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14827 /* port-D for Front */
14828 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14829 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14830 /* port-E for HP out (front panel) */
f12ab1e0
TI
14831 /* this has to be set to VREF80 */
14832 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 14833 /* route front PCM to HP */
9dece1d7 14834 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
14835 /* port-F for mic-in (front panel) with vref */
14836 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14837 /* port-G for CLFE (rear panel) */
14838 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14839 /* port-H for side (rear panel) */
14840 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14841 /* CD-in */
14842 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14843 /* route front mic to ADC1*/
14844 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14845 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14846 /* Unmute DAC0~3 & spdif out*/
14847 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14848 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14849 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14850 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14852 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14853 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14854 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14855 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14856 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14857
7cdbff94
MD
14858 /* Unmute Stereo Mixer 15 */
14859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14861 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
14863
14864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14865 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14866 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14867 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14868 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14869 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14870 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14871 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14872 /* hp used DAC 3 (Front) */
14873 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
14874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14875 { }
14876};
14877
56bb0cab
TI
14878/* additional init verbs for ASUS laptops */
14879static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14880 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14881 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14882 { }
14883};
7cdbff94 14884
df694daa
KY
14885/*
14886 * generic initialization of ADC, input mixers and output mixers
14887 */
14888static struct hda_verb alc861_auto_init_verbs[] = {
14889 /*
14890 * Unmute ADC0 and set the default input to mic-in
14891 */
f12ab1e0 14892 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 14893 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14894
df694daa
KY
14895 /* Unmute DAC0~3 & spdif out*/
14896 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14897 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14898 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14899 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14900 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14901
df694daa
KY
14902 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14903 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14904 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14905 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14906 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14907
df694daa
KY
14908 /* Unmute Stereo Mixer 15 */
14909 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14912 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14913
1c20930a
TI
14914 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14915 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14916 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14917 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14918 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14919 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14920 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14921 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
14922
14923 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14924 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14925 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
14927 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14928 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
14929 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14930 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 14931
f12ab1e0 14932 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
14933
14934 { }
14935};
14936
a53d1aec
TD
14937static struct hda_verb alc861_toshiba_init_verbs[] = {
14938 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 14939
a53d1aec
TD
14940 { }
14941};
14942
14943/* toggle speaker-output according to the hp-jack state */
14944static void alc861_toshiba_automute(struct hda_codec *codec)
14945{
864f92be 14946 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 14947
47fd830a
TI
14948 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14949 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14950 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14951 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
14952}
14953
14954static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14955 unsigned int res)
14956{
a53d1aec
TD
14957 if ((res >> 26) == ALC880_HP_EVENT)
14958 alc861_toshiba_automute(codec);
14959}
14960
def319f9 14961/* pcm configuration: identical with ALC880 */
df694daa
KY
14962#define alc861_pcm_analog_playback alc880_pcm_analog_playback
14963#define alc861_pcm_analog_capture alc880_pcm_analog_capture
14964#define alc861_pcm_digital_playback alc880_pcm_digital_playback
14965#define alc861_pcm_digital_capture alc880_pcm_digital_capture
14966
14967
14968#define ALC861_DIGOUT_NID 0x07
14969
14970static struct hda_channel_mode alc861_8ch_modes[1] = {
14971 { 8, NULL }
14972};
14973
14974static hda_nid_t alc861_dac_nids[4] = {
14975 /* front, surround, clfe, side */
14976 0x03, 0x06, 0x05, 0x04
14977};
14978
9c7f852e
TI
14979static hda_nid_t alc660_dac_nids[3] = {
14980 /* front, clfe, surround */
14981 0x03, 0x05, 0x06
14982};
14983
df694daa
KY
14984static hda_nid_t alc861_adc_nids[1] = {
14985 /* ADC0-2 */
14986 0x08,
14987};
14988
14989static struct hda_input_mux alc861_capture_source = {
14990 .num_items = 5,
14991 .items = {
14992 { "Mic", 0x0 },
14993 { "Front Mic", 0x3 },
14994 { "Line", 0x1 },
14995 { "CD", 0x4 },
14996 { "Mixer", 0x5 },
14997 },
14998};
14999
1c20930a
TI
15000static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15001{
15002 struct alc_spec *spec = codec->spec;
15003 hda_nid_t mix, srcs[5];
15004 int i, j, num;
15005
15006 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15007 return 0;
15008 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15009 if (num < 0)
15010 return 0;
15011 for (i = 0; i < num; i++) {
15012 unsigned int type;
a22d543a 15013 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15014 if (type != AC_WID_AUD_OUT)
15015 continue;
15016 for (j = 0; j < spec->multiout.num_dacs; j++)
15017 if (spec->multiout.dac_nids[j] == srcs[i])
15018 break;
15019 if (j >= spec->multiout.num_dacs)
15020 return srcs[i];
15021 }
15022 return 0;
15023}
15024
df694daa 15025/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15026static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15027 const struct auto_pin_cfg *cfg)
df694daa 15028{
1c20930a 15029 struct alc_spec *spec = codec->spec;
df694daa 15030 int i;
1c20930a 15031 hda_nid_t nid, dac;
df694daa
KY
15032
15033 spec->multiout.dac_nids = spec->private_dac_nids;
15034 for (i = 0; i < cfg->line_outs; i++) {
15035 nid = cfg->line_out_pins[i];
1c20930a
TI
15036 dac = alc861_look_for_dac(codec, nid);
15037 if (!dac)
15038 continue;
15039 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15040 }
df694daa
KY
15041 return 0;
15042}
15043
1c20930a
TI
15044static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15045 hda_nid_t nid, unsigned int chs)
15046{
0afe5f89 15047 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15048 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15049}
15050
df694daa 15051/* add playback controls from the parsed DAC table */
1c20930a 15052static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15053 const struct auto_pin_cfg *cfg)
15054{
1c20930a 15055 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15056 static const char *chname[4] = {
15057 "Front", "Surround", NULL /*CLFE*/, "Side"
15058 };
df694daa 15059 hda_nid_t nid;
1c20930a
TI
15060 int i, err;
15061
15062 if (cfg->line_outs == 1) {
15063 const char *pfx = NULL;
15064 if (!cfg->hp_outs)
15065 pfx = "Master";
15066 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15067 pfx = "Speaker";
15068 if (pfx) {
15069 nid = spec->multiout.dac_nids[0];
15070 return alc861_create_out_sw(codec, pfx, nid, 3);
15071 }
15072 }
df694daa
KY
15073
15074 for (i = 0; i < cfg->line_outs; i++) {
15075 nid = spec->multiout.dac_nids[i];
f12ab1e0 15076 if (!nid)
df694daa 15077 continue;
1c20930a 15078 if (i == 2) {
df694daa 15079 /* Center/LFE */
1c20930a 15080 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15081 if (err < 0)
df694daa 15082 return err;
1c20930a 15083 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15084 if (err < 0)
df694daa
KY
15085 return err;
15086 } else {
1c20930a 15087 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15088 if (err < 0)
df694daa
KY
15089 return err;
15090 }
15091 }
15092 return 0;
15093}
15094
1c20930a 15095static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15096{
1c20930a 15097 struct alc_spec *spec = codec->spec;
df694daa
KY
15098 int err;
15099 hda_nid_t nid;
15100
f12ab1e0 15101 if (!pin)
df694daa
KY
15102 return 0;
15103
15104 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15105 nid = alc861_look_for_dac(codec, pin);
15106 if (nid) {
15107 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15108 if (err < 0)
15109 return err;
15110 spec->multiout.hp_nid = nid;
15111 }
df694daa
KY
15112 }
15113 return 0;
15114}
15115
15116/* create playback/capture controls for input pins */
05f5f477 15117static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15118 const struct auto_pin_cfg *cfg)
df694daa 15119{
05f5f477 15120 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15121}
15122
f12ab1e0
TI
15123static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15124 hda_nid_t nid,
1c20930a 15125 int pin_type, hda_nid_t dac)
df694daa 15126{
1c20930a
TI
15127 hda_nid_t mix, srcs[5];
15128 int i, num;
15129
564c5bea
JL
15130 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15131 pin_type);
1c20930a 15132 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15133 AMP_OUT_UNMUTE);
1c20930a
TI
15134 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15135 return;
15136 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15137 if (num < 0)
15138 return;
15139 for (i = 0; i < num; i++) {
15140 unsigned int mute;
15141 if (srcs[i] == dac || srcs[i] == 0x15)
15142 mute = AMP_IN_UNMUTE(i);
15143 else
15144 mute = AMP_IN_MUTE(i);
15145 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15146 mute);
15147 }
df694daa
KY
15148}
15149
15150static void alc861_auto_init_multi_out(struct hda_codec *codec)
15151{
15152 struct alc_spec *spec = codec->spec;
15153 int i;
15154
15155 for (i = 0; i < spec->autocfg.line_outs; i++) {
15156 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15157 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15158 if (nid)
baba8ee9 15159 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15160 spec->multiout.dac_nids[i]);
df694daa
KY
15161 }
15162}
15163
15164static void alc861_auto_init_hp_out(struct hda_codec *codec)
15165{
15166 struct alc_spec *spec = codec->spec;
df694daa 15167
15870f05
TI
15168 if (spec->autocfg.hp_outs)
15169 alc861_auto_set_output_and_unmute(codec,
15170 spec->autocfg.hp_pins[0],
15171 PIN_HP,
1c20930a 15172 spec->multiout.hp_nid);
15870f05
TI
15173 if (spec->autocfg.speaker_outs)
15174 alc861_auto_set_output_and_unmute(codec,
15175 spec->autocfg.speaker_pins[0],
15176 PIN_OUT,
1c20930a 15177 spec->multiout.dac_nids[0]);
df694daa
KY
15178}
15179
15180static void alc861_auto_init_analog_input(struct hda_codec *codec)
15181{
15182 struct alc_spec *spec = codec->spec;
15183 int i;
15184
15185 for (i = 0; i < AUTO_PIN_LAST; i++) {
15186 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15187 if (nid >= 0x0c && nid <= 0x11)
15188 alc_set_input_pin(codec, nid, i);
df694daa
KY
15189 }
15190}
15191
15192/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15193/* return 1 if successful, 0 if the proper config is not found,
15194 * or a negative error code
15195 */
df694daa
KY
15196static int alc861_parse_auto_config(struct hda_codec *codec)
15197{
15198 struct alc_spec *spec = codec->spec;
15199 int err;
15200 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15201
f12ab1e0
TI
15202 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15203 alc861_ignore);
15204 if (err < 0)
df694daa 15205 return err;
f12ab1e0 15206 if (!spec->autocfg.line_outs)
df694daa
KY
15207 return 0; /* can't find valid BIOS pin config */
15208
1c20930a 15209 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15210 if (err < 0)
15211 return err;
1c20930a 15212 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15213 if (err < 0)
15214 return err;
1c20930a 15215 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15216 if (err < 0)
15217 return err;
05f5f477 15218 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15219 if (err < 0)
df694daa
KY
15220 return err;
15221
15222 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15223
0852d7a6 15224 if (spec->autocfg.dig_outs)
df694daa
KY
15225 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15226
603c4019 15227 if (spec->kctls.list)
d88897ea 15228 add_mixer(spec, spec->kctls.list);
df694daa 15229
d88897ea 15230 add_verb(spec, alc861_auto_init_verbs);
df694daa 15231
a1e8d2da 15232 spec->num_mux_defs = 1;
61b9b9b1 15233 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15234
15235 spec->adc_nids = alc861_adc_nids;
15236 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15237 set_capture_mixer(codec);
df694daa 15238
6227cdce 15239 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15240
df694daa
KY
15241 return 1;
15242}
15243
ae6b813a
TI
15244/* additional initialization for auto-configuration model */
15245static void alc861_auto_init(struct hda_codec *codec)
df694daa 15246{
f6c7e546 15247 struct alc_spec *spec = codec->spec;
df694daa
KY
15248 alc861_auto_init_multi_out(codec);
15249 alc861_auto_init_hp_out(codec);
15250 alc861_auto_init_analog_input(codec);
f6c7e546 15251 if (spec->unsol_event)
7fb0d78f 15252 alc_inithook(codec);
df694daa
KY
15253}
15254
cb53c626
TI
15255#ifdef CONFIG_SND_HDA_POWER_SAVE
15256static struct hda_amp_list alc861_loopbacks[] = {
15257 { 0x15, HDA_INPUT, 0 },
15258 { 0x15, HDA_INPUT, 1 },
15259 { 0x15, HDA_INPUT, 2 },
15260 { 0x15, HDA_INPUT, 3 },
15261 { } /* end */
15262};
15263#endif
15264
df694daa
KY
15265
15266/*
15267 * configuration and preset
15268 */
f5fcc13c
TI
15269static const char *alc861_models[ALC861_MODEL_LAST] = {
15270 [ALC861_3ST] = "3stack",
15271 [ALC660_3ST] = "3stack-660",
15272 [ALC861_3ST_DIG] = "3stack-dig",
15273 [ALC861_6ST_DIG] = "6stack-dig",
15274 [ALC861_UNIWILL_M31] = "uniwill-m31",
15275 [ALC861_TOSHIBA] = "toshiba",
15276 [ALC861_ASUS] = "asus",
15277 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15278 [ALC861_AUTO] = "auto",
15279};
15280
15281static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15282 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15283 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15284 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15285 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15286 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15287 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15288 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15289 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15290 * Any other models that need this preset?
15291 */
15292 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15293 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15294 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15295 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15296 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15297 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15298 /* FIXME: the below seems conflict */
15299 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15300 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15301 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15302 {}
15303};
15304
15305static struct alc_config_preset alc861_presets[] = {
15306 [ALC861_3ST] = {
15307 .mixers = { alc861_3ST_mixer },
15308 .init_verbs = { alc861_threestack_init_verbs },
15309 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15310 .dac_nids = alc861_dac_nids,
15311 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15312 .channel_mode = alc861_threestack_modes,
4e195a7b 15313 .need_dac_fix = 1,
df694daa
KY
15314 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15315 .adc_nids = alc861_adc_nids,
15316 .input_mux = &alc861_capture_source,
15317 },
15318 [ALC861_3ST_DIG] = {
15319 .mixers = { alc861_base_mixer },
15320 .init_verbs = { alc861_threestack_init_verbs },
15321 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15322 .dac_nids = alc861_dac_nids,
15323 .dig_out_nid = ALC861_DIGOUT_NID,
15324 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15325 .channel_mode = alc861_threestack_modes,
4e195a7b 15326 .need_dac_fix = 1,
df694daa
KY
15327 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15328 .adc_nids = alc861_adc_nids,
15329 .input_mux = &alc861_capture_source,
15330 },
15331 [ALC861_6ST_DIG] = {
15332 .mixers = { alc861_base_mixer },
15333 .init_verbs = { alc861_base_init_verbs },
15334 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15335 .dac_nids = alc861_dac_nids,
15336 .dig_out_nid = ALC861_DIGOUT_NID,
15337 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15338 .channel_mode = alc861_8ch_modes,
15339 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15340 .adc_nids = alc861_adc_nids,
15341 .input_mux = &alc861_capture_source,
15342 },
9c7f852e
TI
15343 [ALC660_3ST] = {
15344 .mixers = { alc861_3ST_mixer },
15345 .init_verbs = { alc861_threestack_init_verbs },
15346 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15347 .dac_nids = alc660_dac_nids,
15348 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15349 .channel_mode = alc861_threestack_modes,
4e195a7b 15350 .need_dac_fix = 1,
9c7f852e
TI
15351 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15352 .adc_nids = alc861_adc_nids,
15353 .input_mux = &alc861_capture_source,
15354 },
22309c3e
TI
15355 [ALC861_UNIWILL_M31] = {
15356 .mixers = { alc861_uniwill_m31_mixer },
15357 .init_verbs = { alc861_uniwill_m31_init_verbs },
15358 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15359 .dac_nids = alc861_dac_nids,
15360 .dig_out_nid = ALC861_DIGOUT_NID,
15361 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15362 .channel_mode = alc861_uniwill_m31_modes,
15363 .need_dac_fix = 1,
15364 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15365 .adc_nids = alc861_adc_nids,
15366 .input_mux = &alc861_capture_source,
15367 },
a53d1aec
TD
15368 [ALC861_TOSHIBA] = {
15369 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15370 .init_verbs = { alc861_base_init_verbs,
15371 alc861_toshiba_init_verbs },
a53d1aec
TD
15372 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15373 .dac_nids = alc861_dac_nids,
15374 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15375 .channel_mode = alc883_3ST_2ch_modes,
15376 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15377 .adc_nids = alc861_adc_nids,
15378 .input_mux = &alc861_capture_source,
15379 .unsol_event = alc861_toshiba_unsol_event,
15380 .init_hook = alc861_toshiba_automute,
15381 },
7cdbff94
MD
15382 [ALC861_ASUS] = {
15383 .mixers = { alc861_asus_mixer },
15384 .init_verbs = { alc861_asus_init_verbs },
15385 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15386 .dac_nids = alc861_dac_nids,
15387 .dig_out_nid = ALC861_DIGOUT_NID,
15388 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15389 .channel_mode = alc861_asus_modes,
15390 .need_dac_fix = 1,
15391 .hp_nid = 0x06,
15392 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15393 .adc_nids = alc861_adc_nids,
15394 .input_mux = &alc861_capture_source,
15395 },
56bb0cab
TI
15396 [ALC861_ASUS_LAPTOP] = {
15397 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15398 .init_verbs = { alc861_asus_init_verbs,
15399 alc861_asus_laptop_init_verbs },
15400 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15401 .dac_nids = alc861_dac_nids,
15402 .dig_out_nid = ALC861_DIGOUT_NID,
15403 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15404 .channel_mode = alc883_3ST_2ch_modes,
15405 .need_dac_fix = 1,
15406 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15407 .adc_nids = alc861_adc_nids,
15408 .input_mux = &alc861_capture_source,
15409 },
15410};
df694daa 15411
cfc9b06f
TI
15412/* Pin config fixes */
15413enum {
15414 PINFIX_FSC_AMILO_PI1505,
15415};
15416
15417static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15418 { 0x0b, 0x0221101f }, /* HP */
15419 { 0x0f, 0x90170310 }, /* speaker */
15420 { }
15421};
15422
15423static const struct alc_fixup alc861_fixups[] = {
15424 [PINFIX_FSC_AMILO_PI1505] = {
15425 .pins = alc861_fsc_amilo_pi1505_pinfix
15426 },
15427};
15428
15429static struct snd_pci_quirk alc861_fixup_tbl[] = {
15430 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15431 {}
15432};
df694daa
KY
15433
15434static int patch_alc861(struct hda_codec *codec)
15435{
15436 struct alc_spec *spec;
15437 int board_config;
15438 int err;
15439
dc041e0b 15440 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15441 if (spec == NULL)
15442 return -ENOMEM;
15443
f12ab1e0 15444 codec->spec = spec;
df694daa 15445
f5fcc13c
TI
15446 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15447 alc861_models,
15448 alc861_cfg_tbl);
9c7f852e 15449
f5fcc13c 15450 if (board_config < 0) {
9a11f1aa
TI
15451 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15452 codec->chip_name);
df694daa
KY
15453 board_config = ALC861_AUTO;
15454 }
15455
cfc9b06f
TI
15456 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
15457
df694daa
KY
15458 if (board_config == ALC861_AUTO) {
15459 /* automatic parse from the BIOS config */
15460 err = alc861_parse_auto_config(codec);
15461 if (err < 0) {
15462 alc_free(codec);
15463 return err;
f12ab1e0 15464 } else if (!err) {
9c7f852e
TI
15465 printk(KERN_INFO
15466 "hda_codec: Cannot set up configuration "
15467 "from BIOS. Using base mode...\n");
df694daa
KY
15468 board_config = ALC861_3ST_DIG;
15469 }
15470 }
15471
680cd536
KK
15472 err = snd_hda_attach_beep_device(codec, 0x23);
15473 if (err < 0) {
15474 alc_free(codec);
15475 return err;
15476 }
15477
df694daa 15478 if (board_config != ALC861_AUTO)
e9c364c0 15479 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15480
df694daa
KY
15481 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15482 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15483
df694daa
KY
15484 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15485 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15486
c7a8eb10
TI
15487 if (!spec->cap_mixer)
15488 set_capture_mixer(codec);
45bdd1c1
TI
15489 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15490
2134ea4f
TI
15491 spec->vmaster_nid = 0x03;
15492
df694daa 15493 codec->patch_ops = alc_patch_ops;
c97259df 15494 if (board_config == ALC861_AUTO) {
ae6b813a 15495 spec->init_hook = alc861_auto_init;
c97259df
DC
15496#ifdef CONFIG_SND_HDA_POWER_SAVE
15497 spec->power_hook = alc_power_eapd;
15498#endif
15499 }
cb53c626
TI
15500#ifdef CONFIG_SND_HDA_POWER_SAVE
15501 if (!spec->loopback.amplist)
15502 spec->loopback.amplist = alc861_loopbacks;
15503#endif
ea1fb29a 15504
1da177e4
LT
15505 return 0;
15506}
15507
f32610ed
JS
15508/*
15509 * ALC861-VD support
15510 *
15511 * Based on ALC882
15512 *
15513 * In addition, an independent DAC
15514 */
15515#define ALC861VD_DIGOUT_NID 0x06
15516
15517static hda_nid_t alc861vd_dac_nids[4] = {
15518 /* front, surr, clfe, side surr */
15519 0x02, 0x03, 0x04, 0x05
15520};
15521
15522/* dac_nids for ALC660vd are in a different order - according to
15523 * Realtek's driver.
def319f9 15524 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15525 * of ALC660vd codecs, but for now there is only 3stack mixer
15526 * - and it is the same as in 861vd.
15527 * adc_nids in ALC660vd are (is) the same as in 861vd
15528 */
15529static hda_nid_t alc660vd_dac_nids[3] = {
15530 /* front, rear, clfe, rear_surr */
15531 0x02, 0x04, 0x03
15532};
15533
15534static hda_nid_t alc861vd_adc_nids[1] = {
15535 /* ADC0 */
15536 0x09,
15537};
15538
e1406348
TI
15539static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15540
f32610ed
JS
15541/* input MUX */
15542/* FIXME: should be a matrix-type input source selection */
15543static struct hda_input_mux alc861vd_capture_source = {
15544 .num_items = 4,
15545 .items = {
15546 { "Mic", 0x0 },
15547 { "Front Mic", 0x1 },
15548 { "Line", 0x2 },
15549 { "CD", 0x4 },
15550 },
15551};
15552
272a527c 15553static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15554 .num_items = 2,
272a527c 15555 .items = {
b419f346
TD
15556 { "Ext Mic", 0x0 },
15557 { "Int Mic", 0x1 },
272a527c
KY
15558 },
15559};
15560
d1a991a6
KY
15561static struct hda_input_mux alc861vd_hp_capture_source = {
15562 .num_items = 2,
15563 .items = {
15564 { "Front Mic", 0x0 },
15565 { "ATAPI Mic", 0x1 },
15566 },
15567};
15568
f32610ed
JS
15569/*
15570 * 2ch mode
15571 */
15572static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15573 { 2, NULL }
15574};
15575
15576/*
15577 * 6ch mode
15578 */
15579static struct hda_verb alc861vd_6stack_ch6_init[] = {
15580 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15581 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15582 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15583 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15584 { } /* end */
15585};
15586
15587/*
15588 * 8ch mode
15589 */
15590static struct hda_verb alc861vd_6stack_ch8_init[] = {
15591 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15592 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15593 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15594 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15595 { } /* end */
15596};
15597
15598static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15599 { 6, alc861vd_6stack_ch6_init },
15600 { 8, alc861vd_6stack_ch8_init },
15601};
15602
15603static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15604 {
15605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15606 .name = "Channel Mode",
15607 .info = alc_ch_mode_info,
15608 .get = alc_ch_mode_get,
15609 .put = alc_ch_mode_put,
15610 },
15611 { } /* end */
15612};
15613
f32610ed
JS
15614/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15615 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15616 */
15617static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15618 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15619 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15620
15621 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15622 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15623
15624 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15625 HDA_OUTPUT),
15626 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15627 HDA_OUTPUT),
15628 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15629 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15630
15631 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15632 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15633
15634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15635
15636 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15639
15640 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15643
15644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15646
15647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15649
f32610ed
JS
15650 { } /* end */
15651};
15652
15653static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15654 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15655 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15656
15657 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15658
15659 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15662
15663 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15666
15667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15669
15670 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15671 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15672
f32610ed
JS
15673 { } /* end */
15674};
15675
bdd148a3
KY
15676static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15677 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15678 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15679 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15680
15681 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15682
15683 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15686
15687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15688 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15689 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15690
15691 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15692 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15693
15694 { } /* end */
15695};
15696
b419f346
TD
15697/* Pin assignment: Speaker=0x14, HP = 0x15,
15698 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
15699 */
15700static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
15701 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15702 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
15703 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15704 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
15705 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
15706 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15707 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15708 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
15709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15710 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
15711 { } /* end */
15712};
15713
d1a991a6
KY
15714/* Pin assignment: Speaker=0x14, Line-out = 0x15,
15715 * Front Mic=0x18, ATAPI Mic = 0x19,
15716 */
15717static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
15718 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15719 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15720 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15721 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15722 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15723 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15724 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15725 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 15726
d1a991a6
KY
15727 { } /* end */
15728};
15729
f32610ed
JS
15730/*
15731 * generic initialization of ADC, input mixers and output mixers
15732 */
15733static struct hda_verb alc861vd_volume_init_verbs[] = {
15734 /*
15735 * Unmute ADC0 and set the default input to mic-in
15736 */
15737 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15738 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15739
15740 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
15741 * the analog-loopback mixer widget
15742 */
15743 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15744 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15745 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15746 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
15749
15750 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
15751 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15752 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15753 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 15754 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
15755
15756 /*
15757 * Set up output mixers (0x02 - 0x05)
15758 */
15759 /* set vol=0 to output mixers */
15760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15761 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15763 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15764
15765 /* set up input amps for analog loopback */
15766 /* Amp Indices: DAC = 0, mixer = 1 */
15767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15769 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15770 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15771 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15772 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15773 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15774 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15775
15776 { }
15777};
15778
15779/*
15780 * 3-stack pin configuration:
15781 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15782 */
15783static struct hda_verb alc861vd_3stack_init_verbs[] = {
15784 /*
15785 * Set pin mode and muting
15786 */
15787 /* set front pin widgets 0x14 for output */
15788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15789 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15790 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15791
15792 /* Mic (rear) pin: input vref at 80% */
15793 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15794 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15795 /* Front Mic pin: input vref at 80% */
15796 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15798 /* Line In pin: input */
15799 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15800 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15801 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15802 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15803 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15804 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15805 /* CD pin widget for input */
15806 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15807
15808 { }
15809};
15810
15811/*
15812 * 6-stack pin configuration:
15813 */
15814static struct hda_verb alc861vd_6stack_init_verbs[] = {
15815 /*
15816 * Set pin mode and muting
15817 */
15818 /* set front pin widgets 0x14 for output */
15819 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15820 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15821 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15822
15823 /* Rear Pin: output 1 (0x0d) */
15824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15827 /* CLFE Pin: output 2 (0x0e) */
15828 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15830 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15831 /* Side Pin: output 3 (0x0f) */
15832 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15834 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15835
15836 /* Mic (rear) pin: input vref at 80% */
15837 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15838 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15839 /* Front Mic pin: input vref at 80% */
15840 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15841 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15842 /* Line In pin: input */
15843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15844 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15845 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15846 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15848 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15849 /* CD pin widget for input */
15850 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15851
15852 { }
15853};
15854
bdd148a3
KY
15855static struct hda_verb alc861vd_eapd_verbs[] = {
15856 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15857 { }
15858};
15859
f9423e7a
KY
15860static struct hda_verb alc660vd_eapd_verbs[] = {
15861 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15862 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15863 { }
15864};
15865
bdd148a3
KY
15866static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15867 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15868 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15869 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15870 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 15871 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
15872 {}
15873};
15874
bdd148a3
KY
15875static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15876{
15877 unsigned int present;
15878 unsigned char bits;
15879
864f92be 15880 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 15881 bits = present ? HDA_AMP_MUTE : 0;
864f92be 15882
47fd830a
TI
15883 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15884 HDA_AMP_MUTE, bits);
bdd148a3
KY
15885}
15886
4f5d1706 15887static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 15888{
a9fd4f3f 15889 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
15890 spec->autocfg.hp_pins[0] = 0x1b;
15891 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
15892}
15893
15894static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15895{
a9fd4f3f 15896 alc_automute_amp(codec);
bdd148a3
KY
15897 alc861vd_lenovo_mic_automute(codec);
15898}
15899
15900static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15901 unsigned int res)
15902{
15903 switch (res >> 26) {
bdd148a3
KY
15904 case ALC880_MIC_EVENT:
15905 alc861vd_lenovo_mic_automute(codec);
15906 break;
a9fd4f3f
TI
15907 default:
15908 alc_automute_amp_unsol_event(codec, res);
15909 break;
bdd148a3
KY
15910 }
15911}
15912
272a527c
KY
15913static struct hda_verb alc861vd_dallas_verbs[] = {
15914 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15915 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15916 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15917 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15918
15919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15921 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15922 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15923 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15924 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15925 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15926 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 15927
272a527c
KY
15928 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15929 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15930 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15931 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15932 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15933 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15934 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15935 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15936
15937 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15938 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15939 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15940 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15941 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15943 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15944 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15945
15946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15947 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15948 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15950
15951 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 15952 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
15953 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15954
15955 { } /* end */
15956};
15957
15958/* toggle speaker-output according to the hp-jack state */
4f5d1706 15959static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 15960{
a9fd4f3f 15961 struct alc_spec *spec = codec->spec;
272a527c 15962
a9fd4f3f
TI
15963 spec->autocfg.hp_pins[0] = 0x15;
15964 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
15965}
15966
cb53c626
TI
15967#ifdef CONFIG_SND_HDA_POWER_SAVE
15968#define alc861vd_loopbacks alc880_loopbacks
15969#endif
15970
def319f9 15971/* pcm configuration: identical with ALC880 */
f32610ed
JS
15972#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15973#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15974#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15975#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15976
15977/*
15978 * configuration and preset
15979 */
15980static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15981 [ALC660VD_3ST] = "3stack-660",
983f8ae4 15982 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 15983 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
15984 [ALC861VD_3ST] = "3stack",
15985 [ALC861VD_3ST_DIG] = "3stack-digout",
15986 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 15987 [ALC861VD_LENOVO] = "lenovo",
272a527c 15988 [ALC861VD_DALLAS] = "dallas",
983f8ae4 15989 [ALC861VD_HP] = "hp",
f32610ed
JS
15990 [ALC861VD_AUTO] = "auto",
15991};
15992
15993static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
15994 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15995 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 15996 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 15997 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 15998 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 15999 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16000 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16001 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16002 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16003 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16004 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16005 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16006 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16007 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16008 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16009 {}
16010};
16011
16012static struct alc_config_preset alc861vd_presets[] = {
16013 [ALC660VD_3ST] = {
16014 .mixers = { alc861vd_3st_mixer },
16015 .init_verbs = { alc861vd_volume_init_verbs,
16016 alc861vd_3stack_init_verbs },
16017 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16018 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16019 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16020 .channel_mode = alc861vd_3stack_2ch_modes,
16021 .input_mux = &alc861vd_capture_source,
16022 },
6963f84c
MC
16023 [ALC660VD_3ST_DIG] = {
16024 .mixers = { alc861vd_3st_mixer },
16025 .init_verbs = { alc861vd_volume_init_verbs,
16026 alc861vd_3stack_init_verbs },
16027 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16028 .dac_nids = alc660vd_dac_nids,
16029 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16030 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16031 .channel_mode = alc861vd_3stack_2ch_modes,
16032 .input_mux = &alc861vd_capture_source,
16033 },
f32610ed
JS
16034 [ALC861VD_3ST] = {
16035 .mixers = { alc861vd_3st_mixer },
16036 .init_verbs = { alc861vd_volume_init_verbs,
16037 alc861vd_3stack_init_verbs },
16038 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16039 .dac_nids = alc861vd_dac_nids,
16040 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16041 .channel_mode = alc861vd_3stack_2ch_modes,
16042 .input_mux = &alc861vd_capture_source,
16043 },
16044 [ALC861VD_3ST_DIG] = {
16045 .mixers = { alc861vd_3st_mixer },
16046 .init_verbs = { alc861vd_volume_init_verbs,
16047 alc861vd_3stack_init_verbs },
16048 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16049 .dac_nids = alc861vd_dac_nids,
16050 .dig_out_nid = ALC861VD_DIGOUT_NID,
16051 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16052 .channel_mode = alc861vd_3stack_2ch_modes,
16053 .input_mux = &alc861vd_capture_source,
16054 },
16055 [ALC861VD_6ST_DIG] = {
16056 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16057 .init_verbs = { alc861vd_volume_init_verbs,
16058 alc861vd_6stack_init_verbs },
16059 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16060 .dac_nids = alc861vd_dac_nids,
16061 .dig_out_nid = ALC861VD_DIGOUT_NID,
16062 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16063 .channel_mode = alc861vd_6stack_modes,
16064 .input_mux = &alc861vd_capture_source,
16065 },
bdd148a3
KY
16066 [ALC861VD_LENOVO] = {
16067 .mixers = { alc861vd_lenovo_mixer },
16068 .init_verbs = { alc861vd_volume_init_verbs,
16069 alc861vd_3stack_init_verbs,
16070 alc861vd_eapd_verbs,
16071 alc861vd_lenovo_unsol_verbs },
16072 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16073 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16074 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16075 .channel_mode = alc861vd_3stack_2ch_modes,
16076 .input_mux = &alc861vd_capture_source,
16077 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16078 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16079 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16080 },
272a527c
KY
16081 [ALC861VD_DALLAS] = {
16082 .mixers = { alc861vd_dallas_mixer },
16083 .init_verbs = { alc861vd_dallas_verbs },
16084 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16085 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16086 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16087 .channel_mode = alc861vd_3stack_2ch_modes,
16088 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16089 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16090 .setup = alc861vd_dallas_setup,
16091 .init_hook = alc_automute_amp,
d1a991a6
KY
16092 },
16093 [ALC861VD_HP] = {
16094 .mixers = { alc861vd_hp_mixer },
16095 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16096 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16097 .dac_nids = alc861vd_dac_nids,
d1a991a6 16098 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16099 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16100 .channel_mode = alc861vd_3stack_2ch_modes,
16101 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16102 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16103 .setup = alc861vd_dallas_setup,
16104 .init_hook = alc_automute_amp,
ea1fb29a 16105 },
13c94744
TI
16106 [ALC660VD_ASUS_V1S] = {
16107 .mixers = { alc861vd_lenovo_mixer },
16108 .init_verbs = { alc861vd_volume_init_verbs,
16109 alc861vd_3stack_init_verbs,
16110 alc861vd_eapd_verbs,
16111 alc861vd_lenovo_unsol_verbs },
16112 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16113 .dac_nids = alc660vd_dac_nids,
16114 .dig_out_nid = ALC861VD_DIGOUT_NID,
16115 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16116 .channel_mode = alc861vd_3stack_2ch_modes,
16117 .input_mux = &alc861vd_capture_source,
16118 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16119 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16120 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16121 },
f32610ed
JS
16122};
16123
16124/*
16125 * BIOS auto configuration
16126 */
05f5f477
TI
16127static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16128 const struct auto_pin_cfg *cfg)
16129{
6227cdce 16130 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16131}
16132
16133
f32610ed
JS
16134static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16135 hda_nid_t nid, int pin_type, int dac_idx)
16136{
f6c7e546 16137 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16138}
16139
16140static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16141{
16142 struct alc_spec *spec = codec->spec;
16143 int i;
16144
16145 for (i = 0; i <= HDA_SIDE; i++) {
16146 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16147 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16148 if (nid)
16149 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16150 pin_type, i);
f32610ed
JS
16151 }
16152}
16153
16154
16155static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16156{
16157 struct alc_spec *spec = codec->spec;
16158 hda_nid_t pin;
16159
16160 pin = spec->autocfg.hp_pins[0];
def319f9 16161 if (pin) /* connect to front and use dac 0 */
f32610ed 16162 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16163 pin = spec->autocfg.speaker_pins[0];
16164 if (pin)
16165 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16166}
16167
f32610ed
JS
16168#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16169
16170static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16171{
16172 struct alc_spec *spec = codec->spec;
16173 int i;
16174
16175 for (i = 0; i < AUTO_PIN_LAST; i++) {
16176 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16177 if (alc_is_input_pin(codec, nid)) {
23f0c048 16178 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16179 if (nid != ALC861VD_PIN_CD_NID &&
16180 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16181 snd_hda_codec_write(codec, nid, 0,
16182 AC_VERB_SET_AMP_GAIN_MUTE,
16183 AMP_OUT_MUTE);
16184 }
16185 }
16186}
16187
f511b01c
TI
16188#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16189
f32610ed
JS
16190#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16191#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16192
16193/* add playback controls from the parsed DAC table */
16194/* Based on ALC880 version. But ALC861VD has separate,
16195 * different NIDs for mute/unmute switch and volume control */
16196static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16197 const struct auto_pin_cfg *cfg)
16198{
f32610ed
JS
16199 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16200 hda_nid_t nid_v, nid_s;
16201 int i, err;
16202
16203 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16204 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16205 continue;
16206 nid_v = alc861vd_idx_to_mixer_vol(
16207 alc880_dac_to_idx(
16208 spec->multiout.dac_nids[i]));
16209 nid_s = alc861vd_idx_to_mixer_switch(
16210 alc880_dac_to_idx(
16211 spec->multiout.dac_nids[i]));
16212
16213 if (i == 2) {
16214 /* Center/LFE */
0afe5f89
TI
16215 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16216 "Center",
f12ab1e0
TI
16217 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16218 HDA_OUTPUT));
16219 if (err < 0)
f32610ed 16220 return err;
0afe5f89
TI
16221 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16222 "LFE",
f12ab1e0
TI
16223 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16224 HDA_OUTPUT));
16225 if (err < 0)
f32610ed 16226 return err;
0afe5f89
TI
16227 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16228 "Center",
f12ab1e0
TI
16229 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16230 HDA_INPUT));
16231 if (err < 0)
f32610ed 16232 return err;
0afe5f89
TI
16233 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16234 "LFE",
f12ab1e0
TI
16235 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16236 HDA_INPUT));
16237 if (err < 0)
f32610ed
JS
16238 return err;
16239 } else {
a4fcd491
TI
16240 const char *pfx;
16241 if (cfg->line_outs == 1 &&
16242 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16243 if (!cfg->hp_pins)
16244 pfx = "Speaker";
16245 else
16246 pfx = "PCM";
16247 } else
16248 pfx = chname[i];
0afe5f89 16249 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16250 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16251 HDA_OUTPUT));
16252 if (err < 0)
f32610ed 16253 return err;
a4fcd491
TI
16254 if (cfg->line_outs == 1 &&
16255 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16256 pfx = "Speaker";
0afe5f89 16257 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16258 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16259 HDA_INPUT));
16260 if (err < 0)
f32610ed
JS
16261 return err;
16262 }
16263 }
16264 return 0;
16265}
16266
16267/* add playback controls for speaker and HP outputs */
16268/* Based on ALC880 version. But ALC861VD has separate,
16269 * different NIDs for mute/unmute switch and volume control */
16270static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16271 hda_nid_t pin, const char *pfx)
16272{
16273 hda_nid_t nid_v, nid_s;
16274 int err;
f32610ed 16275
f12ab1e0 16276 if (!pin)
f32610ed
JS
16277 return 0;
16278
16279 if (alc880_is_fixed_pin(pin)) {
16280 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16281 /* specify the DAC as the extra output */
f12ab1e0 16282 if (!spec->multiout.hp_nid)
f32610ed
JS
16283 spec->multiout.hp_nid = nid_v;
16284 else
16285 spec->multiout.extra_out_nid[0] = nid_v;
16286 /* control HP volume/switch on the output mixer amp */
16287 nid_v = alc861vd_idx_to_mixer_vol(
16288 alc880_fixed_pin_idx(pin));
16289 nid_s = alc861vd_idx_to_mixer_switch(
16290 alc880_fixed_pin_idx(pin));
16291
0afe5f89 16292 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16293 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16294 if (err < 0)
f32610ed 16295 return err;
0afe5f89 16296 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16297 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16298 if (err < 0)
f32610ed
JS
16299 return err;
16300 } else if (alc880_is_multi_pin(pin)) {
16301 /* set manual connection */
16302 /* we have only a switch on HP-out PIN */
0afe5f89 16303 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16304 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16305 if (err < 0)
f32610ed
JS
16306 return err;
16307 }
16308 return 0;
16309}
16310
16311/* parse the BIOS configuration and set up the alc_spec
16312 * return 1 if successful, 0 if the proper config is not found,
16313 * or a negative error code
16314 * Based on ALC880 version - had to change it to override
16315 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16316static int alc861vd_parse_auto_config(struct hda_codec *codec)
16317{
16318 struct alc_spec *spec = codec->spec;
16319 int err;
16320 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16321
f12ab1e0
TI
16322 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16323 alc861vd_ignore);
16324 if (err < 0)
f32610ed 16325 return err;
f12ab1e0 16326 if (!spec->autocfg.line_outs)
f32610ed
JS
16327 return 0; /* can't find valid BIOS pin config */
16328
f12ab1e0
TI
16329 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16330 if (err < 0)
16331 return err;
16332 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16333 if (err < 0)
16334 return err;
16335 err = alc861vd_auto_create_extra_out(spec,
16336 spec->autocfg.speaker_pins[0],
16337 "Speaker");
16338 if (err < 0)
16339 return err;
16340 err = alc861vd_auto_create_extra_out(spec,
16341 spec->autocfg.hp_pins[0],
16342 "Headphone");
16343 if (err < 0)
16344 return err;
05f5f477 16345 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16346 if (err < 0)
f32610ed
JS
16347 return err;
16348
16349 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16350
0852d7a6 16351 if (spec->autocfg.dig_outs)
f32610ed
JS
16352 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16353
603c4019 16354 if (spec->kctls.list)
d88897ea 16355 add_mixer(spec, spec->kctls.list);
f32610ed 16356
d88897ea 16357 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16358
16359 spec->num_mux_defs = 1;
61b9b9b1 16360 spec->input_mux = &spec->private_imux[0];
f32610ed 16361
776e184e
TI
16362 err = alc_auto_add_mic_boost(codec);
16363 if (err < 0)
16364 return err;
16365
6227cdce 16366 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16367
f32610ed
JS
16368 return 1;
16369}
16370
16371/* additional initialization for auto-configuration model */
16372static void alc861vd_auto_init(struct hda_codec *codec)
16373{
f6c7e546 16374 struct alc_spec *spec = codec->spec;
f32610ed
JS
16375 alc861vd_auto_init_multi_out(codec);
16376 alc861vd_auto_init_hp_out(codec);
16377 alc861vd_auto_init_analog_input(codec);
f511b01c 16378 alc861vd_auto_init_input_src(codec);
f6c7e546 16379 if (spec->unsol_event)
7fb0d78f 16380 alc_inithook(codec);
f32610ed
JS
16381}
16382
f8f25ba3
TI
16383enum {
16384 ALC660VD_FIX_ASUS_GPIO1
16385};
16386
16387/* reset GPIO1 */
16388static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16389 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16390 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16391 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16392 { }
16393};
16394
16395static const struct alc_fixup alc861vd_fixups[] = {
16396 [ALC660VD_FIX_ASUS_GPIO1] = {
16397 .verbs = alc660vd_fix_asus_gpio1_verbs,
16398 },
16399};
16400
16401static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16402 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16403 {}
16404};
16405
f32610ed
JS
16406static int patch_alc861vd(struct hda_codec *codec)
16407{
16408 struct alc_spec *spec;
16409 int err, board_config;
16410
16411 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16412 if (spec == NULL)
16413 return -ENOMEM;
16414
16415 codec->spec = spec;
16416
16417 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16418 alc861vd_models,
16419 alc861vd_cfg_tbl);
16420
16421 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16422 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16423 codec->chip_name);
f32610ed
JS
16424 board_config = ALC861VD_AUTO;
16425 }
16426
f8f25ba3
TI
16427 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
16428
f32610ed
JS
16429 if (board_config == ALC861VD_AUTO) {
16430 /* automatic parse from the BIOS config */
16431 err = alc861vd_parse_auto_config(codec);
16432 if (err < 0) {
16433 alc_free(codec);
16434 return err;
f12ab1e0 16435 } else if (!err) {
f32610ed
JS
16436 printk(KERN_INFO
16437 "hda_codec: Cannot set up configuration "
16438 "from BIOS. Using base mode...\n");
16439 board_config = ALC861VD_3ST;
16440 }
16441 }
16442
680cd536
KK
16443 err = snd_hda_attach_beep_device(codec, 0x23);
16444 if (err < 0) {
16445 alc_free(codec);
16446 return err;
16447 }
16448
f32610ed 16449 if (board_config != ALC861VD_AUTO)
e9c364c0 16450 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16451
2f893286 16452 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16453 /* always turn on EAPD */
d88897ea 16454 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16455 }
16456
f32610ed
JS
16457 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16458 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16459
f32610ed
JS
16460 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16461 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16462
dd704698
TI
16463 if (!spec->adc_nids) {
16464 spec->adc_nids = alc861vd_adc_nids;
16465 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16466 }
16467 if (!spec->capsrc_nids)
16468 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16469
b59bdf3b 16470 set_capture_mixer(codec);
45bdd1c1 16471 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16472
2134ea4f
TI
16473 spec->vmaster_nid = 0x02;
16474
f32610ed
JS
16475 codec->patch_ops = alc_patch_ops;
16476
16477 if (board_config == ALC861VD_AUTO)
16478 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16479#ifdef CONFIG_SND_HDA_POWER_SAVE
16480 if (!spec->loopback.amplist)
16481 spec->loopback.amplist = alc861vd_loopbacks;
16482#endif
f32610ed
JS
16483
16484 return 0;
16485}
16486
bc9f98a9
KY
16487/*
16488 * ALC662 support
16489 *
16490 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16491 * configuration. Each pin widget can choose any input DACs and a mixer.
16492 * Each ADC is connected from a mixer of all inputs. This makes possible
16493 * 6-channel independent captures.
16494 *
16495 * In addition, an independent DAC for the multi-playback (not used in this
16496 * driver yet).
16497 */
16498#define ALC662_DIGOUT_NID 0x06
16499#define ALC662_DIGIN_NID 0x0a
16500
16501static hda_nid_t alc662_dac_nids[4] = {
16502 /* front, rear, clfe, rear_surr */
16503 0x02, 0x03, 0x04
16504};
16505
622e84cd
KY
16506static hda_nid_t alc272_dac_nids[2] = {
16507 0x02, 0x03
16508};
16509
b59bdf3b 16510static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16511 /* ADC1-2 */
b59bdf3b 16512 0x09, 0x08
bc9f98a9 16513};
e1406348 16514
622e84cd
KY
16515static hda_nid_t alc272_adc_nids[1] = {
16516 /* ADC1-2 */
16517 0x08,
16518};
16519
b59bdf3b 16520static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16521static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16522
e1406348 16523
bc9f98a9
KY
16524/* input MUX */
16525/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16526static struct hda_input_mux alc662_capture_source = {
16527 .num_items = 4,
16528 .items = {
16529 { "Mic", 0x0 },
16530 { "Front Mic", 0x1 },
16531 { "Line", 0x2 },
16532 { "CD", 0x4 },
16533 },
16534};
16535
16536static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16537 .num_items = 2,
16538 .items = {
16539 { "Mic", 0x1 },
16540 { "Line", 0x2 },
16541 },
16542};
291702f0 16543
6dda9f4a
KY
16544static struct hda_input_mux alc663_capture_source = {
16545 .num_items = 3,
16546 .items = {
16547 { "Mic", 0x0 },
16548 { "Front Mic", 0x1 },
16549 { "Line", 0x2 },
16550 },
16551};
16552
4f5d1706 16553#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16554static struct hda_input_mux alc272_nc10_capture_source = {
16555 .num_items = 16,
16556 .items = {
16557 { "Autoselect Mic", 0x0 },
16558 { "Internal Mic", 0x1 },
16559 { "In-0x02", 0x2 },
16560 { "In-0x03", 0x3 },
16561 { "In-0x04", 0x4 },
16562 { "In-0x05", 0x5 },
16563 { "In-0x06", 0x6 },
16564 { "In-0x07", 0x7 },
16565 { "In-0x08", 0x8 },
16566 { "In-0x09", 0x9 },
16567 { "In-0x0a", 0x0a },
16568 { "In-0x0b", 0x0b },
16569 { "In-0x0c", 0x0c },
16570 { "In-0x0d", 0x0d },
16571 { "In-0x0e", 0x0e },
16572 { "In-0x0f", 0x0f },
16573 },
16574};
16575#endif
16576
bc9f98a9
KY
16577/*
16578 * 2ch mode
16579 */
16580static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16581 { 2, NULL }
16582};
16583
16584/*
16585 * 2ch mode
16586 */
16587static struct hda_verb alc662_3ST_ch2_init[] = {
16588 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16589 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16590 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16591 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16592 { } /* end */
16593};
16594
16595/*
16596 * 6ch mode
16597 */
16598static struct hda_verb alc662_3ST_ch6_init[] = {
16599 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16600 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16601 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16602 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16603 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16604 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16605 { } /* end */
16606};
16607
16608static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16609 { 2, alc662_3ST_ch2_init },
16610 { 6, alc662_3ST_ch6_init },
16611};
16612
16613/*
16614 * 2ch mode
16615 */
16616static struct hda_verb alc662_sixstack_ch6_init[] = {
16617 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16618 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16619 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16620 { } /* end */
16621};
16622
16623/*
16624 * 6ch mode
16625 */
16626static struct hda_verb alc662_sixstack_ch8_init[] = {
16627 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16628 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16629 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16630 { } /* end */
16631};
16632
16633static struct hda_channel_mode alc662_5stack_modes[2] = {
16634 { 2, alc662_sixstack_ch6_init },
16635 { 6, alc662_sixstack_ch8_init },
16636};
16637
16638/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16639 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16640 */
16641
16642static struct snd_kcontrol_new alc662_base_mixer[] = {
16643 /* output mixer control */
16644 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16645 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16646 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16647 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16648 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16649 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16650 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16651 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16652 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16653
16654 /*Input mixer control */
16655 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16656 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16657 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16658 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16659 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16660 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16661 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16662 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16663 { } /* end */
16664};
16665
16666static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16667 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16668 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
16669 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16670 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16671 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16672 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16673 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16676 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16677 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16678 { } /* end */
16679};
16680
16681static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16682 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16683 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16684 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 16685 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16686 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16687 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16688 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16689 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16690 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16691 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16692 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16693 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16694 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16697 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16698 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16699 { } /* end */
16700};
16701
16702static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16703 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16704 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
16705 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16706 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
16707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16712 { } /* end */
16713};
16714
291702f0 16715static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
16716 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16717 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
16718
16719 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
16720 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16721 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16722
16723 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16724 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16725 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16726 { } /* end */
16727};
16728
8c427226 16729static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
16730 ALC262_HIPPO_MASTER_SWITCH,
16731 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 16732 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
16733 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16734 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
16735 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
16736 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16737 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16740 { } /* end */
16741};
16742
f1d4e28b
KY
16743static struct hda_bind_ctls alc663_asus_bind_master_vol = {
16744 .ops = &snd_hda_bind_vol,
16745 .values = {
16746 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16747 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
16748 0
16749 },
16750};
16751
16752static struct hda_bind_ctls alc663_asus_one_bind_switch = {
16753 .ops = &snd_hda_bind_sw,
16754 .values = {
16755 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16756 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16757 0
16758 },
16759};
16760
6dda9f4a 16761static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
16762 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16763 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16766 { } /* end */
16767};
16768
16769static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16770 .ops = &snd_hda_bind_sw,
16771 .values = {
16772 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16773 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16774 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16775 0
16776 },
16777};
16778
16779static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16780 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16781 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16782 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16784 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16785 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16786
16787 { } /* end */
16788};
16789
16790static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16791 .ops = &snd_hda_bind_sw,
16792 .values = {
16793 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16794 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16795 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16796 0
16797 },
16798};
16799
16800static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16801 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16802 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16805 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16806 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16807 { } /* end */
16808};
16809
16810static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
16811 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16812 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
16813 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16816 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16817 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16818 { } /* end */
16819};
16820
16821static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16822 .ops = &snd_hda_bind_vol,
16823 .values = {
16824 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16825 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16826 0
16827 },
16828};
16829
16830static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16831 .ops = &snd_hda_bind_sw,
16832 .values = {
16833 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16834 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16835 0
16836 },
16837};
16838
16839static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16840 HDA_BIND_VOL("Master Playback Volume",
16841 &alc663_asus_two_bind_master_vol),
16842 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16843 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
16844 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
16847 { } /* end */
16848};
16849
16850static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16851 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16852 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16853 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
16857 { } /* end */
16858};
16859
16860static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16861 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16862 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16863 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16864 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16865 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16866
16867 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16868 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16869 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16870 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16871 { } /* end */
16872};
16873
16874static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16876 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16878
16879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16881 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16882 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16883 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16884 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16885 { } /* end */
16886};
16887
ebb83eeb
KY
16888static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
16889 .ops = &snd_hda_bind_sw,
16890 .values = {
16891 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16892 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16893 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16894 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16895 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16896 0
16897 },
16898};
16899
16900static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
16901 .ops = &snd_hda_bind_sw,
16902 .values = {
16903 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16904 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16905 0
16906 },
16907};
16908
16909static struct snd_kcontrol_new alc663_mode7_mixer[] = {
16910 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16911 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16912 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16913 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16914 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16915 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16916 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16919 { } /* end */
16920};
16921
16922static struct snd_kcontrol_new alc663_mode8_mixer[] = {
16923 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16924 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16925 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16926 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16927 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16929 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16930 { } /* end */
16931};
16932
16933
bc9f98a9
KY
16934static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16935 {
16936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16937 .name = "Channel Mode",
16938 .info = alc_ch_mode_info,
16939 .get = alc_ch_mode_get,
16940 .put = alc_ch_mode_put,
16941 },
16942 { } /* end */
16943};
16944
16945static struct hda_verb alc662_init_verbs[] = {
16946 /* ADC: mute amp left and right */
16947 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16948 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 16949
b60dd394
KY
16950 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16951 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16952 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16953 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16954 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
16956
16957 /* Front Pin: output 0 (0x0c) */
16958 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16959 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16960
16961 /* Rear Pin: output 1 (0x0d) */
16962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16963 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16964
16965 /* CLFE Pin: output 2 (0x0e) */
16966 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16967 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16968
16969 /* Mic (rear) pin: input vref at 80% */
16970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16971 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16972 /* Front Mic pin: input vref at 80% */
16973 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16974 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16975 /* Line In pin: input */
16976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16978 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16980 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16981 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16982 /* CD pin widget for input */
16983 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16984
16985 /* FIXME: use matrix-type input source selection */
16986 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16987 /* Input mixer */
16988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 16989 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
16990
16991 /* always trun on EAPD */
16992 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16993 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16994
bc9f98a9
KY
16995 { }
16996};
16997
cec27c89
KY
16998static struct hda_verb alc663_init_verbs[] = {
16999 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17000 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17001 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17002 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17005 { }
17006};
17007
17008static struct hda_verb alc272_init_verbs[] = {
17009 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17010 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17011 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17012 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17013 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17014 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17015 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17016 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17017 { }
17018};
17019
bc9f98a9
KY
17020static struct hda_verb alc662_sue_init_verbs[] = {
17021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17022 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17023 {}
17024};
17025
17026static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17027 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17028 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17029 {}
bc9f98a9
KY
17030};
17031
8c427226
KY
17032/* Set Unsolicited Event*/
17033static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17034 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17035 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17036 {}
17037};
17038
6dda9f4a 17039static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17040 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17041 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17042 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17043 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17044 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17047 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17048 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17049 {}
17050};
17051
17052static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17053 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17054 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17055 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17058 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17059 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17060 {}
17061};
17062
17063static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17064 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17065 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17066 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17067 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17069 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17070 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17071 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17072 {}
17073};
6dda9f4a 17074
f1d4e28b
KY
17075static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17077 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17078 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17079 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17080 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17081 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17082 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17083 {}
17084};
6dda9f4a 17085
f1d4e28b
KY
17086static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17087 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17088 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17089 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17090 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17094 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17095 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17096 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17097 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17098 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17099 {}
17100};
17101
17102static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17103 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17104 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17105 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17106 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17108 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17109 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17112 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17113 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17114 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17115 {}
17116};
17117
17118static struct hda_verb alc663_g71v_init_verbs[] = {
17119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17120 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17121 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17122
17123 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17124 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17125 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17126
17127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17128 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17129 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17130 {}
17131};
17132
17133static struct hda_verb alc663_g50v_init_verbs[] = {
17134 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17135 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17136 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17137
17138 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17139 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17140 {}
17141};
17142
f1d4e28b
KY
17143static struct hda_verb alc662_ecs_init_verbs[] = {
17144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17146 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17147 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17148 {}
17149};
17150
622e84cd
KY
17151static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17152 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17153 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17154 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17155 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17156 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17157 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17158 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17160 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17161 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17162 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17163 {}
17164};
17165
17166static struct hda_verb alc272_dell_init_verbs[] = {
17167 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17168 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17170 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17171 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17172 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17173 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17174 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17176 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17177 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17178 {}
17179};
17180
ebb83eeb
KY
17181static struct hda_verb alc663_mode7_init_verbs[] = {
17182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17184 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17185 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17186 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17187 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17189 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17190 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17191 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17192 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17193 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17194 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17195 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17196 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17197 {}
17198};
17199
17200static struct hda_verb alc663_mode8_init_verbs[] = {
17201 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17205 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17206 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17207 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17208 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17209 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17210 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17211 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17212 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17213 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17214 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17215 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17216 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17217 {}
17218};
17219
f1d4e28b
KY
17220static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17221 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17222 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17223 { } /* end */
17224};
17225
622e84cd
KY
17226static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17227 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17228 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17229 { } /* end */
17230};
17231
bc9f98a9
KY
17232static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17233{
17234 unsigned int present;
f12ab1e0 17235 unsigned char bits;
bc9f98a9 17236
864f92be 17237 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17238 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17239
47fd830a
TI
17240 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17241 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17242}
17243
17244static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17245{
17246 unsigned int present;
f12ab1e0 17247 unsigned char bits;
bc9f98a9 17248
864f92be 17249 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17250 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17251
47fd830a
TI
17252 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17253 HDA_AMP_MUTE, bits);
17254 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17255 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17256}
17257
17258static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17259 unsigned int res)
17260{
17261 if ((res >> 26) == ALC880_HP_EVENT)
17262 alc662_lenovo_101e_all_automute(codec);
17263 if ((res >> 26) == ALC880_FRONT_EVENT)
17264 alc662_lenovo_101e_ispeaker_automute(codec);
17265}
17266
291702f0
KY
17267/* unsolicited event for HP jack sensing */
17268static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17269 unsigned int res)
17270{
291702f0 17271 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17272 alc_mic_automute(codec);
42171c17
TI
17273 else
17274 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17275}
17276
4f5d1706
TI
17277static void alc662_eeepc_setup(struct hda_codec *codec)
17278{
17279 struct alc_spec *spec = codec->spec;
17280
17281 alc262_hippo1_setup(codec);
17282 spec->ext_mic.pin = 0x18;
17283 spec->ext_mic.mux_idx = 0;
17284 spec->int_mic.pin = 0x19;
17285 spec->int_mic.mux_idx = 1;
17286 spec->auto_mic = 1;
17287}
17288
291702f0
KY
17289static void alc662_eeepc_inithook(struct hda_codec *codec)
17290{
4f5d1706
TI
17291 alc262_hippo_automute(codec);
17292 alc_mic_automute(codec);
291702f0
KY
17293}
17294
4f5d1706 17295static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17296{
42171c17
TI
17297 struct alc_spec *spec = codec->spec;
17298
17299 spec->autocfg.hp_pins[0] = 0x14;
17300 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17301}
17302
4f5d1706
TI
17303#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17304
6dda9f4a
KY
17305static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17306{
17307 unsigned int present;
17308 unsigned char bits;
17309
864f92be 17310 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17311 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17312 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17313 HDA_AMP_MUTE, bits);
f1d4e28b 17314 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17315 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17316}
17317
17318static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17319{
17320 unsigned int present;
17321 unsigned char bits;
17322
864f92be 17323 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17324 bits = present ? HDA_AMP_MUTE : 0;
17325 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17326 HDA_AMP_MUTE, bits);
f1d4e28b 17327 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17328 HDA_AMP_MUTE, bits);
f1d4e28b 17329 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17330 HDA_AMP_MUTE, bits);
f1d4e28b 17331 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17332 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17333}
17334
17335static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17336{
17337 unsigned int present;
17338 unsigned char bits;
17339
864f92be 17340 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17341 bits = present ? HDA_AMP_MUTE : 0;
17342 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17343 HDA_AMP_MUTE, bits);
f1d4e28b 17344 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17345 HDA_AMP_MUTE, bits);
f1d4e28b 17346 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17347 HDA_AMP_MUTE, bits);
f1d4e28b 17348 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17349 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17350}
17351
17352static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17353{
17354 unsigned int present;
17355 unsigned char bits;
17356
864f92be 17357 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17358 bits = present ? 0 : PIN_OUT;
17359 snd_hda_codec_write(codec, 0x14, 0,
17360 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17361}
17362
17363static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17364{
17365 unsigned int present1, present2;
17366
864f92be
WF
17367 present1 = snd_hda_jack_detect(codec, 0x21);
17368 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17369
17370 if (present1 || present2) {
17371 snd_hda_codec_write_cache(codec, 0x14, 0,
17372 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17373 } else {
17374 snd_hda_codec_write_cache(codec, 0x14, 0,
17375 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17376 }
17377}
17378
17379static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17380{
17381 unsigned int present1, present2;
17382
864f92be
WF
17383 present1 = snd_hda_jack_detect(codec, 0x1b);
17384 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17385
17386 if (present1 || present2) {
17387 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17388 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17389 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17390 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17391 } else {
17392 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17393 HDA_AMP_MUTE, 0);
f1d4e28b 17394 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17395 HDA_AMP_MUTE, 0);
f1d4e28b 17396 }
6dda9f4a
KY
17397}
17398
ebb83eeb
KY
17399static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17400{
17401 unsigned int present1, present2;
17402
17403 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17404 AC_VERB_GET_PIN_SENSE, 0)
17405 & AC_PINSENSE_PRESENCE;
17406 present2 = snd_hda_codec_read(codec, 0x21, 0,
17407 AC_VERB_GET_PIN_SENSE, 0)
17408 & AC_PINSENSE_PRESENCE;
17409
17410 if (present1 || present2) {
17411 snd_hda_codec_write_cache(codec, 0x14, 0,
17412 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17413 snd_hda_codec_write_cache(codec, 0x17, 0,
17414 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17415 } else {
17416 snd_hda_codec_write_cache(codec, 0x14, 0,
17417 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17418 snd_hda_codec_write_cache(codec, 0x17, 0,
17419 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17420 }
17421}
17422
17423static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17424{
17425 unsigned int present1, present2;
17426
17427 present1 = snd_hda_codec_read(codec, 0x21, 0,
17428 AC_VERB_GET_PIN_SENSE, 0)
17429 & AC_PINSENSE_PRESENCE;
17430 present2 = snd_hda_codec_read(codec, 0x15, 0,
17431 AC_VERB_GET_PIN_SENSE, 0)
17432 & AC_PINSENSE_PRESENCE;
17433
17434 if (present1 || present2) {
17435 snd_hda_codec_write_cache(codec, 0x14, 0,
17436 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17437 snd_hda_codec_write_cache(codec, 0x17, 0,
17438 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17439 } else {
17440 snd_hda_codec_write_cache(codec, 0x14, 0,
17441 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17442 snd_hda_codec_write_cache(codec, 0x17, 0,
17443 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17444 }
17445}
17446
6dda9f4a
KY
17447static void alc663_m51va_unsol_event(struct hda_codec *codec,
17448 unsigned int res)
17449{
17450 switch (res >> 26) {
17451 case ALC880_HP_EVENT:
17452 alc663_m51va_speaker_automute(codec);
17453 break;
17454 case ALC880_MIC_EVENT:
4f5d1706 17455 alc_mic_automute(codec);
6dda9f4a
KY
17456 break;
17457 }
17458}
17459
4f5d1706
TI
17460static void alc663_m51va_setup(struct hda_codec *codec)
17461{
17462 struct alc_spec *spec = codec->spec;
17463 spec->ext_mic.pin = 0x18;
17464 spec->ext_mic.mux_idx = 0;
17465 spec->int_mic.pin = 0x12;
ebb83eeb 17466 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17467 spec->auto_mic = 1;
17468}
17469
6dda9f4a
KY
17470static void alc663_m51va_inithook(struct hda_codec *codec)
17471{
17472 alc663_m51va_speaker_automute(codec);
4f5d1706 17473 alc_mic_automute(codec);
6dda9f4a
KY
17474}
17475
f1d4e28b 17476/* ***************** Mode1 ******************************/
4f5d1706 17477#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17478
17479static void alc663_mode1_setup(struct hda_codec *codec)
17480{
17481 struct alc_spec *spec = codec->spec;
17482 spec->ext_mic.pin = 0x18;
17483 spec->ext_mic.mux_idx = 0;
17484 spec->int_mic.pin = 0x19;
17485 spec->int_mic.mux_idx = 1;
17486 spec->auto_mic = 1;
17487}
17488
4f5d1706 17489#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17490
f1d4e28b
KY
17491/* ***************** Mode2 ******************************/
17492static void alc662_mode2_unsol_event(struct hda_codec *codec,
17493 unsigned int res)
17494{
17495 switch (res >> 26) {
17496 case ALC880_HP_EVENT:
17497 alc662_f5z_speaker_automute(codec);
17498 break;
17499 case ALC880_MIC_EVENT:
4f5d1706 17500 alc_mic_automute(codec);
f1d4e28b
KY
17501 break;
17502 }
17503}
17504
ebb83eeb 17505#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17506
f1d4e28b
KY
17507static void alc662_mode2_inithook(struct hda_codec *codec)
17508{
17509 alc662_f5z_speaker_automute(codec);
4f5d1706 17510 alc_mic_automute(codec);
f1d4e28b
KY
17511}
17512/* ***************** Mode3 ******************************/
17513static void alc663_mode3_unsol_event(struct hda_codec *codec,
17514 unsigned int res)
17515{
17516 switch (res >> 26) {
17517 case ALC880_HP_EVENT:
17518 alc663_two_hp_m1_speaker_automute(codec);
17519 break;
17520 case ALC880_MIC_EVENT:
4f5d1706 17521 alc_mic_automute(codec);
f1d4e28b
KY
17522 break;
17523 }
17524}
17525
ebb83eeb 17526#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17527
f1d4e28b
KY
17528static void alc663_mode3_inithook(struct hda_codec *codec)
17529{
17530 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17531 alc_mic_automute(codec);
f1d4e28b
KY
17532}
17533/* ***************** Mode4 ******************************/
17534static void alc663_mode4_unsol_event(struct hda_codec *codec,
17535 unsigned int res)
17536{
17537 switch (res >> 26) {
17538 case ALC880_HP_EVENT:
17539 alc663_21jd_two_speaker_automute(codec);
17540 break;
17541 case ALC880_MIC_EVENT:
4f5d1706 17542 alc_mic_automute(codec);
f1d4e28b
KY
17543 break;
17544 }
17545}
17546
ebb83eeb 17547#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17548
f1d4e28b
KY
17549static void alc663_mode4_inithook(struct hda_codec *codec)
17550{
17551 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17552 alc_mic_automute(codec);
f1d4e28b
KY
17553}
17554/* ***************** Mode5 ******************************/
17555static void alc663_mode5_unsol_event(struct hda_codec *codec,
17556 unsigned int res)
17557{
17558 switch (res >> 26) {
17559 case ALC880_HP_EVENT:
17560 alc663_15jd_two_speaker_automute(codec);
17561 break;
17562 case ALC880_MIC_EVENT:
4f5d1706 17563 alc_mic_automute(codec);
f1d4e28b
KY
17564 break;
17565 }
17566}
17567
ebb83eeb 17568#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17569
f1d4e28b
KY
17570static void alc663_mode5_inithook(struct hda_codec *codec)
17571{
17572 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17573 alc_mic_automute(codec);
f1d4e28b
KY
17574}
17575/* ***************** Mode6 ******************************/
17576static void alc663_mode6_unsol_event(struct hda_codec *codec,
17577 unsigned int res)
17578{
17579 switch (res >> 26) {
17580 case ALC880_HP_EVENT:
17581 alc663_two_hp_m2_speaker_automute(codec);
17582 break;
17583 case ALC880_MIC_EVENT:
4f5d1706 17584 alc_mic_automute(codec);
f1d4e28b
KY
17585 break;
17586 }
17587}
17588
ebb83eeb 17589#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17590
f1d4e28b
KY
17591static void alc663_mode6_inithook(struct hda_codec *codec)
17592{
17593 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17594 alc_mic_automute(codec);
f1d4e28b
KY
17595}
17596
ebb83eeb
KY
17597/* ***************** Mode7 ******************************/
17598static void alc663_mode7_unsol_event(struct hda_codec *codec,
17599 unsigned int res)
17600{
17601 switch (res >> 26) {
17602 case ALC880_HP_EVENT:
17603 alc663_two_hp_m7_speaker_automute(codec);
17604 break;
17605 case ALC880_MIC_EVENT:
17606 alc_mic_automute(codec);
17607 break;
17608 }
17609}
17610
17611#define alc663_mode7_setup alc663_mode1_setup
17612
17613static void alc663_mode7_inithook(struct hda_codec *codec)
17614{
17615 alc663_two_hp_m7_speaker_automute(codec);
17616 alc_mic_automute(codec);
17617}
17618
17619/* ***************** Mode8 ******************************/
17620static void alc663_mode8_unsol_event(struct hda_codec *codec,
17621 unsigned int res)
17622{
17623 switch (res >> 26) {
17624 case ALC880_HP_EVENT:
17625 alc663_two_hp_m8_speaker_automute(codec);
17626 break;
17627 case ALC880_MIC_EVENT:
17628 alc_mic_automute(codec);
17629 break;
17630 }
17631}
17632
17633#define alc663_mode8_setup alc663_m51va_setup
17634
17635static void alc663_mode8_inithook(struct hda_codec *codec)
17636{
17637 alc663_two_hp_m8_speaker_automute(codec);
17638 alc_mic_automute(codec);
17639}
17640
6dda9f4a
KY
17641static void alc663_g71v_hp_automute(struct hda_codec *codec)
17642{
17643 unsigned int present;
17644 unsigned char bits;
17645
864f92be 17646 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17647 bits = present ? HDA_AMP_MUTE : 0;
17648 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17649 HDA_AMP_MUTE, bits);
17650 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17651 HDA_AMP_MUTE, bits);
17652}
17653
17654static void alc663_g71v_front_automute(struct hda_codec *codec)
17655{
17656 unsigned int present;
17657 unsigned char bits;
17658
864f92be 17659 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17660 bits = present ? HDA_AMP_MUTE : 0;
17661 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17662 HDA_AMP_MUTE, bits);
17663}
17664
17665static void alc663_g71v_unsol_event(struct hda_codec *codec,
17666 unsigned int res)
17667{
17668 switch (res >> 26) {
17669 case ALC880_HP_EVENT:
17670 alc663_g71v_hp_automute(codec);
17671 break;
17672 case ALC880_FRONT_EVENT:
17673 alc663_g71v_front_automute(codec);
17674 break;
17675 case ALC880_MIC_EVENT:
4f5d1706 17676 alc_mic_automute(codec);
6dda9f4a
KY
17677 break;
17678 }
17679}
17680
4f5d1706
TI
17681#define alc663_g71v_setup alc663_m51va_setup
17682
6dda9f4a
KY
17683static void alc663_g71v_inithook(struct hda_codec *codec)
17684{
17685 alc663_g71v_front_automute(codec);
17686 alc663_g71v_hp_automute(codec);
4f5d1706 17687 alc_mic_automute(codec);
6dda9f4a
KY
17688}
17689
17690static void alc663_g50v_unsol_event(struct hda_codec *codec,
17691 unsigned int res)
17692{
17693 switch (res >> 26) {
17694 case ALC880_HP_EVENT:
17695 alc663_m51va_speaker_automute(codec);
17696 break;
17697 case ALC880_MIC_EVENT:
4f5d1706 17698 alc_mic_automute(codec);
6dda9f4a
KY
17699 break;
17700 }
17701}
17702
4f5d1706
TI
17703#define alc663_g50v_setup alc663_m51va_setup
17704
6dda9f4a
KY
17705static void alc663_g50v_inithook(struct hda_codec *codec)
17706{
17707 alc663_m51va_speaker_automute(codec);
4f5d1706 17708 alc_mic_automute(codec);
6dda9f4a
KY
17709}
17710
f1d4e28b
KY
17711static struct snd_kcontrol_new alc662_ecs_mixer[] = {
17712 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 17713 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
17714
17715 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
17716 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17717 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17718
17719 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17720 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17721 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17722 { } /* end */
17723};
17724
9541ba1d
CP
17725static struct snd_kcontrol_new alc272_nc10_mixer[] = {
17726 /* Master Playback automatically created from Speaker and Headphone */
17727 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17728 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17729 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17730 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17731
17732 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17733 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17734 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
17735
17736 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17737 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17738 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
17739 { } /* end */
17740};
17741
cb53c626
TI
17742#ifdef CONFIG_SND_HDA_POWER_SAVE
17743#define alc662_loopbacks alc880_loopbacks
17744#endif
17745
bc9f98a9 17746
def319f9 17747/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
17748#define alc662_pcm_analog_playback alc880_pcm_analog_playback
17749#define alc662_pcm_analog_capture alc880_pcm_analog_capture
17750#define alc662_pcm_digital_playback alc880_pcm_digital_playback
17751#define alc662_pcm_digital_capture alc880_pcm_digital_capture
17752
17753/*
17754 * configuration and preset
17755 */
17756static const char *alc662_models[ALC662_MODEL_LAST] = {
17757 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17758 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17759 [ALC662_3ST_6ch] = "3stack-6ch",
17760 [ALC662_5ST_DIG] = "6stack-dig",
17761 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 17762 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 17763 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 17764 [ALC662_ECS] = "ecs",
6dda9f4a
KY
17765 [ALC663_ASUS_M51VA] = "m51va",
17766 [ALC663_ASUS_G71V] = "g71v",
17767 [ALC663_ASUS_H13] = "h13",
17768 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
17769 [ALC663_ASUS_MODE1] = "asus-mode1",
17770 [ALC662_ASUS_MODE2] = "asus-mode2",
17771 [ALC663_ASUS_MODE3] = "asus-mode3",
17772 [ALC663_ASUS_MODE4] = "asus-mode4",
17773 [ALC663_ASUS_MODE5] = "asus-mode5",
17774 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
17775 [ALC663_ASUS_MODE7] = "asus-mode7",
17776 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
17777 [ALC272_DELL] = "dell",
17778 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 17779 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
17780 [ALC662_AUTO] = "auto",
17781};
17782
17783static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 17784 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
17785 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17786 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 17787 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 17788 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 17789 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 17790 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 17791 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 17792 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 17793 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
17794 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17795 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 17796 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17797 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17798 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17799 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17800 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17801 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 17802 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17803 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17804 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
17805 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17806 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17807 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17808 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 17809 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
17810 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17811 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17812 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 17813 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17814 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17815 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17816 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 17817 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 17818 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17819 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17820 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17821 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 17822 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 17823 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 17824 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 17825 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
17826 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17827 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
17828 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17829 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17830 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 17831 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
17832 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17833 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 17834 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
17835 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17836 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17837 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17838 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17839 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 17840 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 17841 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 17842 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
17843 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17844 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17845 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17846 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
17847 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17848 ALC662_3ST_6ch_DIG),
4dee8baa 17849 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 17850 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
17851 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17852 ALC662_3ST_6ch_DIG),
6227cdce 17853 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 17854 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 17855 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 17856 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 17857 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 17858 ALC662_3ST_6ch_DIG),
dea0a509
TI
17859 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17860 ALC663_ASUS_H13),
7aee6746 17861 SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
bc9f98a9
KY
17862 {}
17863};
17864
17865static struct alc_config_preset alc662_presets[] = {
17866 [ALC662_3ST_2ch_DIG] = {
f9e336f6 17867 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
17868 .init_verbs = { alc662_init_verbs },
17869 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17870 .dac_nids = alc662_dac_nids,
17871 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17872 .dig_in_nid = ALC662_DIGIN_NID,
17873 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17874 .channel_mode = alc662_3ST_2ch_modes,
17875 .input_mux = &alc662_capture_source,
17876 },
17877 [ALC662_3ST_6ch_DIG] = {
f9e336f6 17878 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17879 .init_verbs = { alc662_init_verbs },
17880 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17881 .dac_nids = alc662_dac_nids,
17882 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17883 .dig_in_nid = ALC662_DIGIN_NID,
17884 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17885 .channel_mode = alc662_3ST_6ch_modes,
17886 .need_dac_fix = 1,
17887 .input_mux = &alc662_capture_source,
f12ab1e0 17888 },
bc9f98a9 17889 [ALC662_3ST_6ch] = {
f9e336f6 17890 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17891 .init_verbs = { alc662_init_verbs },
17892 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17893 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17894 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17895 .channel_mode = alc662_3ST_6ch_modes,
17896 .need_dac_fix = 1,
17897 .input_mux = &alc662_capture_source,
f12ab1e0 17898 },
bc9f98a9 17899 [ALC662_5ST_DIG] = {
f9e336f6 17900 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
17901 .init_verbs = { alc662_init_verbs },
17902 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17903 .dac_nids = alc662_dac_nids,
17904 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17905 .dig_in_nid = ALC662_DIGIN_NID,
17906 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17907 .channel_mode = alc662_5stack_modes,
17908 .input_mux = &alc662_capture_source,
17909 },
17910 [ALC662_LENOVO_101E] = {
f9e336f6 17911 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
17912 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
17913 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17914 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17915 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17916 .channel_mode = alc662_3ST_2ch_modes,
17917 .input_mux = &alc662_lenovo_101e_capture_source,
17918 .unsol_event = alc662_lenovo_101e_unsol_event,
17919 .init_hook = alc662_lenovo_101e_all_automute,
17920 },
291702f0 17921 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 17922 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
17923 .init_verbs = { alc662_init_verbs,
17924 alc662_eeepc_sue_init_verbs },
17925 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17926 .dac_nids = alc662_dac_nids,
291702f0
KY
17927 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17928 .channel_mode = alc662_3ST_2ch_modes,
291702f0 17929 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17930 .setup = alc662_eeepc_setup,
291702f0
KY
17931 .init_hook = alc662_eeepc_inithook,
17932 },
8c427226 17933 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 17934 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
17935 alc662_chmode_mixer },
17936 .init_verbs = { alc662_init_verbs,
17937 alc662_eeepc_ep20_sue_init_verbs },
17938 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17939 .dac_nids = alc662_dac_nids,
8c427226
KY
17940 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17941 .channel_mode = alc662_3ST_6ch_modes,
17942 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 17943 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17944 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
17945 .init_hook = alc662_eeepc_ep20_inithook,
17946 },
f1d4e28b 17947 [ALC662_ECS] = {
f9e336f6 17948 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
17949 .init_verbs = { alc662_init_verbs,
17950 alc662_ecs_init_verbs },
17951 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17952 .dac_nids = alc662_dac_nids,
17953 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17954 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 17955 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 17956 .setup = alc662_eeepc_setup,
f1d4e28b
KY
17957 .init_hook = alc662_eeepc_inithook,
17958 },
6dda9f4a 17959 [ALC663_ASUS_M51VA] = {
f9e336f6 17960 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
17961 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17962 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17963 .dac_nids = alc662_dac_nids,
17964 .dig_out_nid = ALC662_DIGOUT_NID,
17965 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17966 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 17967 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 17968 .setup = alc663_m51va_setup,
6dda9f4a
KY
17969 .init_hook = alc663_m51va_inithook,
17970 },
17971 [ALC663_ASUS_G71V] = {
f9e336f6 17972 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
17973 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17974 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17975 .dac_nids = alc662_dac_nids,
17976 .dig_out_nid = ALC662_DIGOUT_NID,
17977 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17978 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 17979 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 17980 .setup = alc663_g71v_setup,
6dda9f4a
KY
17981 .init_hook = alc663_g71v_inithook,
17982 },
17983 [ALC663_ASUS_H13] = {
f9e336f6 17984 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
17985 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17986 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17987 .dac_nids = alc662_dac_nids,
17988 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17989 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
17990 .unsol_event = alc663_m51va_unsol_event,
17991 .init_hook = alc663_m51va_inithook,
17992 },
17993 [ALC663_ASUS_G50V] = {
f9e336f6 17994 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
17995 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
17996 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17997 .dac_nids = alc662_dac_nids,
17998 .dig_out_nid = ALC662_DIGOUT_NID,
17999 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18000 .channel_mode = alc662_3ST_6ch_modes,
18001 .input_mux = &alc663_capture_source,
18002 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18003 .setup = alc663_g50v_setup,
6dda9f4a
KY
18004 .init_hook = alc663_g50v_inithook,
18005 },
f1d4e28b 18006 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18007 .mixers = { alc663_m51va_mixer },
18008 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18009 .init_verbs = { alc662_init_verbs,
18010 alc663_21jd_amic_init_verbs },
18011 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18012 .hp_nid = 0x03,
18013 .dac_nids = alc662_dac_nids,
18014 .dig_out_nid = ALC662_DIGOUT_NID,
18015 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18016 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18017 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18018 .setup = alc663_mode1_setup,
f1d4e28b
KY
18019 .init_hook = alc663_mode1_inithook,
18020 },
18021 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18022 .mixers = { alc662_1bjd_mixer },
18023 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18024 .init_verbs = { alc662_init_verbs,
18025 alc662_1bjd_amic_init_verbs },
18026 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18027 .dac_nids = alc662_dac_nids,
18028 .dig_out_nid = ALC662_DIGOUT_NID,
18029 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18030 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18031 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18032 .setup = alc662_mode2_setup,
f1d4e28b
KY
18033 .init_hook = alc662_mode2_inithook,
18034 },
18035 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18036 .mixers = { alc663_two_hp_m1_mixer },
18037 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18038 .init_verbs = { alc662_init_verbs,
18039 alc663_two_hp_amic_m1_init_verbs },
18040 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18041 .hp_nid = 0x03,
18042 .dac_nids = alc662_dac_nids,
18043 .dig_out_nid = ALC662_DIGOUT_NID,
18044 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18045 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18046 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18047 .setup = alc663_mode3_setup,
f1d4e28b
KY
18048 .init_hook = alc663_mode3_inithook,
18049 },
18050 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18051 .mixers = { alc663_asus_21jd_clfe_mixer },
18052 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18053 .init_verbs = { alc662_init_verbs,
18054 alc663_21jd_amic_init_verbs},
18055 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18056 .hp_nid = 0x03,
18057 .dac_nids = alc662_dac_nids,
18058 .dig_out_nid = ALC662_DIGOUT_NID,
18059 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18060 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18061 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18062 .setup = alc663_mode4_setup,
f1d4e28b
KY
18063 .init_hook = alc663_mode4_inithook,
18064 },
18065 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18066 .mixers = { alc663_asus_15jd_clfe_mixer },
18067 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18068 .init_verbs = { alc662_init_verbs,
18069 alc663_15jd_amic_init_verbs },
18070 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18071 .hp_nid = 0x03,
18072 .dac_nids = alc662_dac_nids,
18073 .dig_out_nid = ALC662_DIGOUT_NID,
18074 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18075 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18076 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18077 .setup = alc663_mode5_setup,
f1d4e28b
KY
18078 .init_hook = alc663_mode5_inithook,
18079 },
18080 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18081 .mixers = { alc663_two_hp_m2_mixer },
18082 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18083 .init_verbs = { alc662_init_verbs,
18084 alc663_two_hp_amic_m2_init_verbs },
18085 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18086 .hp_nid = 0x03,
18087 .dac_nids = alc662_dac_nids,
18088 .dig_out_nid = ALC662_DIGOUT_NID,
18089 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18090 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18091 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18092 .setup = alc663_mode6_setup,
f1d4e28b
KY
18093 .init_hook = alc663_mode6_inithook,
18094 },
ebb83eeb
KY
18095 [ALC663_ASUS_MODE7] = {
18096 .mixers = { alc663_mode7_mixer },
18097 .cap_mixer = alc662_auto_capture_mixer,
18098 .init_verbs = { alc662_init_verbs,
18099 alc663_mode7_init_verbs },
18100 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18101 .hp_nid = 0x03,
18102 .dac_nids = alc662_dac_nids,
18103 .dig_out_nid = ALC662_DIGOUT_NID,
18104 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18105 .channel_mode = alc662_3ST_2ch_modes,
18106 .unsol_event = alc663_mode7_unsol_event,
18107 .setup = alc663_mode7_setup,
18108 .init_hook = alc663_mode7_inithook,
18109 },
18110 [ALC663_ASUS_MODE8] = {
18111 .mixers = { alc663_mode8_mixer },
18112 .cap_mixer = alc662_auto_capture_mixer,
18113 .init_verbs = { alc662_init_verbs,
18114 alc663_mode8_init_verbs },
18115 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18116 .hp_nid = 0x03,
18117 .dac_nids = alc662_dac_nids,
18118 .dig_out_nid = ALC662_DIGOUT_NID,
18119 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18120 .channel_mode = alc662_3ST_2ch_modes,
18121 .unsol_event = alc663_mode8_unsol_event,
18122 .setup = alc663_mode8_setup,
18123 .init_hook = alc663_mode8_inithook,
18124 },
622e84cd
KY
18125 [ALC272_DELL] = {
18126 .mixers = { alc663_m51va_mixer },
18127 .cap_mixer = alc272_auto_capture_mixer,
18128 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18129 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18130 .dac_nids = alc662_dac_nids,
18131 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18132 .adc_nids = alc272_adc_nids,
18133 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18134 .capsrc_nids = alc272_capsrc_nids,
18135 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18136 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18137 .setup = alc663_m51va_setup,
622e84cd
KY
18138 .init_hook = alc663_m51va_inithook,
18139 },
18140 [ALC272_DELL_ZM1] = {
18141 .mixers = { alc663_m51va_mixer },
18142 .cap_mixer = alc662_auto_capture_mixer,
18143 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18144 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18145 .dac_nids = alc662_dac_nids,
18146 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18147 .adc_nids = alc662_adc_nids,
b59bdf3b 18148 .num_adc_nids = 1,
622e84cd
KY
18149 .capsrc_nids = alc662_capsrc_nids,
18150 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18151 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18152 .setup = alc663_m51va_setup,
622e84cd
KY
18153 .init_hook = alc663_m51va_inithook,
18154 },
9541ba1d
CP
18155 [ALC272_SAMSUNG_NC10] = {
18156 .mixers = { alc272_nc10_mixer },
18157 .init_verbs = { alc662_init_verbs,
18158 alc663_21jd_amic_init_verbs },
18159 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18160 .dac_nids = alc272_dac_nids,
18161 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18162 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18163 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18164 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18165 .setup = alc663_mode4_setup,
9541ba1d
CP
18166 .init_hook = alc663_mode4_inithook,
18167 },
bc9f98a9
KY
18168};
18169
18170
18171/*
18172 * BIOS auto configuration
18173 */
18174
7085ec12
TI
18175/* convert from MIX nid to DAC */
18176static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18177{
18178 if (nid == 0x0f)
18179 return 0x02;
18180 else if (nid >= 0x0c && nid <= 0x0e)
18181 return nid - 0x0c + 0x02;
18182 else
18183 return 0;
18184}
18185
18186/* get MIX nid connected to the given pin targeted to DAC */
18187static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18188 hda_nid_t dac)
18189{
18190 hda_nid_t mix[4];
18191 int i, num;
18192
18193 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18194 for (i = 0; i < num; i++) {
18195 if (alc662_mix_to_dac(mix[i]) == dac)
18196 return mix[i];
18197 }
18198 return 0;
18199}
18200
18201/* look for an empty DAC slot */
18202static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18203{
18204 struct alc_spec *spec = codec->spec;
18205 hda_nid_t srcs[5];
18206 int i, j, num;
18207
18208 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18209 if (num < 0)
18210 return 0;
18211 for (i = 0; i < num; i++) {
18212 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18213 if (!nid)
18214 continue;
18215 for (j = 0; j < spec->multiout.num_dacs; j++)
18216 if (spec->multiout.dac_nids[j] == nid)
18217 break;
18218 if (j >= spec->multiout.num_dacs)
18219 return nid;
18220 }
18221 return 0;
18222}
18223
18224/* fill in the dac_nids table from the parsed pin configuration */
18225static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18226 const struct auto_pin_cfg *cfg)
18227{
18228 struct alc_spec *spec = codec->spec;
18229 int i;
18230 hda_nid_t dac;
18231
18232 spec->multiout.dac_nids = spec->private_dac_nids;
18233 for (i = 0; i < cfg->line_outs; i++) {
18234 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18235 if (!dac)
18236 continue;
18237 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18238 }
18239 return 0;
18240}
18241
0afe5f89 18242static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18243 hda_nid_t nid, unsigned int chs)
18244{
0afe5f89 18245 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18246 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18247}
18248
0afe5f89 18249static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18250 hda_nid_t nid, unsigned int chs)
18251{
0afe5f89 18252 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18253 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18254}
18255
18256#define alc662_add_stereo_vol(spec, pfx, nid) \
18257 alc662_add_vol_ctl(spec, pfx, nid, 3)
18258#define alc662_add_stereo_sw(spec, pfx, nid) \
18259 alc662_add_sw_ctl(spec, pfx, nid, 3)
18260
bc9f98a9 18261/* add playback controls from the parsed DAC table */
7085ec12 18262static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18263 const struct auto_pin_cfg *cfg)
18264{
7085ec12 18265 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18266 static const char *chname[4] = {
18267 "Front", "Surround", NULL /*CLFE*/, "Side"
18268 };
7085ec12 18269 hda_nid_t nid, mix;
bc9f98a9
KY
18270 int i, err;
18271
18272 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18273 nid = spec->multiout.dac_nids[i];
18274 if (!nid)
18275 continue;
18276 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18277 if (!mix)
bc9f98a9 18278 continue;
bc9f98a9
KY
18279 if (i == 2) {
18280 /* Center/LFE */
7085ec12 18281 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18282 if (err < 0)
18283 return err;
7085ec12 18284 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18285 if (err < 0)
18286 return err;
7085ec12 18287 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18288 if (err < 0)
18289 return err;
7085ec12 18290 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18291 if (err < 0)
18292 return err;
18293 } else {
0d884cb9
TI
18294 const char *pfx;
18295 if (cfg->line_outs == 1 &&
18296 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18297 if (cfg->hp_outs)
0d884cb9
TI
18298 pfx = "Speaker";
18299 else
18300 pfx = "PCM";
18301 } else
18302 pfx = chname[i];
7085ec12 18303 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18304 if (err < 0)
18305 return err;
0d884cb9
TI
18306 if (cfg->line_outs == 1 &&
18307 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18308 pfx = "Speaker";
7085ec12 18309 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18310 if (err < 0)
18311 return err;
18312 }
18313 }
18314 return 0;
18315}
18316
18317/* add playback controls for speaker and HP outputs */
7085ec12
TI
18318/* return DAC nid if any new DAC is assigned */
18319static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18320 const char *pfx)
18321{
7085ec12
TI
18322 struct alc_spec *spec = codec->spec;
18323 hda_nid_t nid, mix;
bc9f98a9 18324 int err;
bc9f98a9
KY
18325
18326 if (!pin)
18327 return 0;
7085ec12
TI
18328 nid = alc662_look_for_dac(codec, pin);
18329 if (!nid) {
7085ec12
TI
18330 /* the corresponding DAC is already occupied */
18331 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18332 return 0; /* no way */
18333 /* create a switch only */
0afe5f89 18334 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18335 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18336 }
18337
7085ec12
TI
18338 mix = alc662_dac_to_mix(codec, pin, nid);
18339 if (!mix)
18340 return 0;
18341 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18342 if (err < 0)
18343 return err;
18344 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18345 if (err < 0)
18346 return err;
18347 return nid;
bc9f98a9
KY
18348}
18349
18350/* create playback/capture controls for input pins */
05f5f477 18351#define alc662_auto_create_input_ctls \
4b7348a1 18352 alc882_auto_create_input_ctls
bc9f98a9
KY
18353
18354static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18355 hda_nid_t nid, int pin_type,
7085ec12 18356 hda_nid_t dac)
bc9f98a9 18357{
7085ec12
TI
18358 int i, num;
18359 hda_nid_t srcs[4];
18360
f6c7e546 18361 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18362 /* need the manual connection? */
7085ec12
TI
18363 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18364 if (num <= 1)
18365 return;
18366 for (i = 0; i < num; i++) {
18367 if (alc662_mix_to_dac(srcs[i]) != dac)
18368 continue;
18369 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18370 return;
bc9f98a9
KY
18371 }
18372}
18373
18374static void alc662_auto_init_multi_out(struct hda_codec *codec)
18375{
18376 struct alc_spec *spec = codec->spec;
7085ec12 18377 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18378 int i;
18379
18380 for (i = 0; i <= HDA_SIDE; i++) {
18381 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18382 if (nid)
baba8ee9 18383 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18384 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18385 }
18386}
18387
18388static void alc662_auto_init_hp_out(struct hda_codec *codec)
18389{
18390 struct alc_spec *spec = codec->spec;
18391 hda_nid_t pin;
18392
18393 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18394 if (pin)
18395 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18396 spec->multiout.hp_nid);
f6c7e546
TI
18397 pin = spec->autocfg.speaker_pins[0];
18398 if (pin)
7085ec12
TI
18399 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18400 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18401}
18402
bc9f98a9
KY
18403#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18404
18405static void alc662_auto_init_analog_input(struct hda_codec *codec)
18406{
18407 struct alc_spec *spec = codec->spec;
18408 int i;
18409
18410 for (i = 0; i < AUTO_PIN_LAST; i++) {
18411 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18412 if (alc_is_input_pin(codec, nid)) {
23f0c048 18413 alc_set_input_pin(codec, nid, i);
52ca15b7 18414 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18415 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18416 snd_hda_codec_write(codec, nid, 0,
18417 AC_VERB_SET_AMP_GAIN_MUTE,
18418 AMP_OUT_MUTE);
18419 }
18420 }
18421}
18422
f511b01c
TI
18423#define alc662_auto_init_input_src alc882_auto_init_input_src
18424
bc9f98a9
KY
18425static int alc662_parse_auto_config(struct hda_codec *codec)
18426{
18427 struct alc_spec *spec = codec->spec;
18428 int err;
18429 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18430
18431 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18432 alc662_ignore);
18433 if (err < 0)
18434 return err;
18435 if (!spec->autocfg.line_outs)
18436 return 0; /* can't find valid BIOS pin config */
18437
7085ec12 18438 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18439 if (err < 0)
18440 return err;
7085ec12 18441 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18442 if (err < 0)
18443 return err;
7085ec12 18444 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18445 spec->autocfg.speaker_pins[0],
18446 "Speaker");
18447 if (err < 0)
18448 return err;
7085ec12
TI
18449 if (err)
18450 spec->multiout.extra_out_nid[0] = err;
18451 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18452 "Headphone");
18453 if (err < 0)
18454 return err;
7085ec12
TI
18455 if (err)
18456 spec->multiout.hp_nid = err;
05f5f477 18457 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18458 if (err < 0)
bc9f98a9
KY
18459 return err;
18460
18461 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18462
0852d7a6 18463 if (spec->autocfg.dig_outs)
bc9f98a9
KY
18464 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18465
603c4019 18466 if (spec->kctls.list)
d88897ea 18467 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18468
18469 spec->num_mux_defs = 1;
61b9b9b1 18470 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18471
cec27c89
KY
18472 add_verb(spec, alc662_init_verbs);
18473 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18474 codec->vendor_id == 0x10ec0665)
18475 add_verb(spec, alc663_init_verbs);
18476
18477 if (codec->vendor_id == 0x10ec0272)
18478 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18479
18480 err = alc_auto_add_mic_boost(codec);
18481 if (err < 0)
18482 return err;
18483
6227cdce
KY
18484 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18485 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18486 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18487 else
18488 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18489
8c87286f 18490 return 1;
bc9f98a9
KY
18491}
18492
18493/* additional initialization for auto-configuration model */
18494static void alc662_auto_init(struct hda_codec *codec)
18495{
f6c7e546 18496 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18497 alc662_auto_init_multi_out(codec);
18498 alc662_auto_init_hp_out(codec);
18499 alc662_auto_init_analog_input(codec);
f511b01c 18500 alc662_auto_init_input_src(codec);
f6c7e546 18501 if (spec->unsol_event)
7fb0d78f 18502 alc_inithook(codec);
bc9f98a9
KY
18503}
18504
18505static int patch_alc662(struct hda_codec *codec)
18506{
18507 struct alc_spec *spec;
18508 int err, board_config;
18509
18510 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18511 if (!spec)
18512 return -ENOMEM;
18513
18514 codec->spec = spec;
18515
da00c244
KY
18516 alc_auto_parse_customize_define(codec);
18517
2c3bf9ab
TI
18518 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18519
c027ddcd
KY
18520 if (alc_read_coef_idx(codec, 0) == 0x8020)
18521 alc_codec_rename(codec, "ALC661");
18522 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18523 codec->bus->pci->subsystem_vendor == 0x1025 &&
18524 spec->cdefine.platform_type == 1)
18525 alc_codec_rename(codec, "ALC272X");
274693f3 18526
bc9f98a9
KY
18527 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18528 alc662_models,
18529 alc662_cfg_tbl);
18530 if (board_config < 0) {
9a11f1aa
TI
18531 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18532 codec->chip_name);
bc9f98a9
KY
18533 board_config = ALC662_AUTO;
18534 }
18535
18536 if (board_config == ALC662_AUTO) {
18537 /* automatic parse from the BIOS config */
18538 err = alc662_parse_auto_config(codec);
18539 if (err < 0) {
18540 alc_free(codec);
18541 return err;
8c87286f 18542 } else if (!err) {
bc9f98a9
KY
18543 printk(KERN_INFO
18544 "hda_codec: Cannot set up configuration "
18545 "from BIOS. Using base mode...\n");
18546 board_config = ALC662_3ST_2ch_DIG;
18547 }
18548 }
18549
680cd536
KK
18550 err = snd_hda_attach_beep_device(codec, 0x1);
18551 if (err < 0) {
18552 alc_free(codec);
18553 return err;
18554 }
18555
bc9f98a9 18556 if (board_config != ALC662_AUTO)
e9c364c0 18557 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18558
bc9f98a9
KY
18559 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18560 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18561
bc9f98a9
KY
18562 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18563 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18564
dd704698
TI
18565 if (!spec->adc_nids) {
18566 spec->adc_nids = alc662_adc_nids;
18567 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18568 }
18569 if (!spec->capsrc_nids)
18570 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18571
f9e336f6 18572 if (!spec->cap_mixer)
b59bdf3b 18573 set_capture_mixer(codec);
cec27c89 18574
da00c244
KY
18575 if (spec->cdefine.enable_pcbeep) {
18576 switch (codec->vendor_id) {
18577 case 0x10ec0662:
18578 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18579 break;
18580 case 0x10ec0272:
18581 case 0x10ec0663:
18582 case 0x10ec0665:
18583 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18584 break;
18585 case 0x10ec0273:
18586 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18587 break;
18588 }
cec27c89 18589 }
2134ea4f
TI
18590 spec->vmaster_nid = 0x02;
18591
bc9f98a9
KY
18592 codec->patch_ops = alc_patch_ops;
18593 if (board_config == ALC662_AUTO)
18594 spec->init_hook = alc662_auto_init;
cb53c626
TI
18595#ifdef CONFIG_SND_HDA_POWER_SAVE
18596 if (!spec->loopback.amplist)
18597 spec->loopback.amplist = alc662_loopbacks;
18598#endif
bc9f98a9
KY
18599
18600 return 0;
18601}
18602
274693f3
KY
18603static int patch_alc888(struct hda_codec *codec)
18604{
18605 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18606 kfree(codec->chip_name);
18607 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18608 if (!codec->chip_name) {
18609 alc_free(codec);
274693f3 18610 return -ENOMEM;
ac2c92e0
TI
18611 }
18612 return patch_alc662(codec);
274693f3 18613 }
ac2c92e0 18614 return patch_alc882(codec);
274693f3
KY
18615}
18616
1da177e4
LT
18617/*
18618 * patch entries
18619 */
1289e9e8 18620static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 18621 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 18622 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 18623 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 18624 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 18625 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 18626 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 18627 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 18628 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 18629 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 18630 .patch = patch_alc861 },
f32610ed
JS
18631 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
18632 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
18633 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 18634 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 18635 .patch = patch_alc882 },
bc9f98a9
KY
18636 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18637 .patch = patch_alc662 },
6dda9f4a 18638 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 18639 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 18640 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
f32610ed 18641 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 18642 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 18643 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 18644 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 18645 .patch = patch_alc882 },
cb308f97 18646 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 18647 .patch = patch_alc882 },
df694daa 18648 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 18649 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 18650 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 18651 .patch = patch_alc882 },
274693f3 18652 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 18653 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 18654 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
18655 {} /* terminator */
18656};
1289e9e8
TI
18657
18658MODULE_ALIAS("snd-hda-codec-id:10ec*");
18659
18660MODULE_LICENSE("GPL");
18661MODULE_DESCRIPTION("Realtek HD-audio codec");
18662
18663static struct hda_codec_preset_list realtek_list = {
18664 .preset = snd_hda_preset_realtek,
18665 .owner = THIS_MODULE,
18666};
18667
18668static int __init patch_realtek_init(void)
18669{
18670 return snd_hda_add_codec_preset(&realtek_list);
18671}
18672
18673static void __exit patch_realtek_exit(void)
18674{
18675 snd_hda_delete_codec_preset(&realtek_list);
18676}
18677
18678module_init(patch_realtek_init)
18679module_exit(patch_realtek_exit)