]> 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,
7ad7b218 233 ALC883_MEDION_WIM2160,
b373bdeb 234 ALC883_LAPTOP_EAPD,
bc9f98a9 235 ALC883_LENOVO_101E_2ch,
272a527c 236 ALC883_LENOVO_NB0763,
189609ae 237 ALC888_LENOVO_MS7195_DIG,
e2757d5e 238 ALC888_LENOVO_SKY,
ea1fb29a 239 ALC883_HAIER_W66,
4723c022 240 ALC888_3ST_HP,
5795b9e6 241 ALC888_6ST_DELL,
a8848bd6 242 ALC883_MITAC,
a65cc60f 243 ALC883_CLEVO_M540R,
0c4cc443 244 ALC883_CLEVO_M720,
fb97dc67 245 ALC883_FUJITSU_PI2515,
ef8ef5fb 246 ALC888_FUJITSU_XA3530,
17bba1b7 247 ALC883_3ST_6ch_INTEL,
87a8c370
JK
248 ALC889A_INTEL,
249 ALC889_INTEL,
e2757d5e
KY
250 ALC888_ASUS_M90V,
251 ALC888_ASUS_EEE1601,
eb4c41d3 252 ALC889A_MB31,
3ab90935 253 ALC1200_ASUS_P5Q,
3e1647c5 254 ALC883_SONY_VAIO_TT,
4953550a
TI
255 ALC882_AUTO,
256 ALC882_MODEL_LAST,
9c7f852e
TI
257};
258
d4a86d81
TI
259/* ALC680 models */
260enum {
261 ALC680_BASE,
262 ALC680_AUTO,
263 ALC680_MODEL_LAST,
264};
265
df694daa
KY
266/* for GPIO Poll */
267#define GPIO_MASK 0x03
268
4a79ba34
TI
269/* extra amp-initialization sequence types */
270enum {
271 ALC_INIT_NONE,
272 ALC_INIT_DEFAULT,
273 ALC_INIT_GPIO1,
274 ALC_INIT_GPIO2,
275 ALC_INIT_GPIO3,
276};
277
6c819492
TI
278struct alc_mic_route {
279 hda_nid_t pin;
280 unsigned char mux_idx;
281 unsigned char amix_idx;
282};
283
284#define MUX_IDX_UNDEF ((unsigned char)-1)
285
da00c244
KY
286struct alc_customize_define {
287 unsigned int sku_cfg;
288 unsigned char port_connectivity;
289 unsigned char check_sum;
290 unsigned char customization;
291 unsigned char external_amp;
292 unsigned int enable_pcbeep:1;
293 unsigned int platform_type:1;
294 unsigned int swap:1;
295 unsigned int override:1;
296};
297
1da177e4
LT
298struct alc_spec {
299 /* codec parameterization */
df694daa 300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 301 unsigned int num_mixers;
f9e336f6 302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 304
2d9c6482 305 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
306 * don't forget NULL
307 * termination!
e9edcee0
TI
308 */
309 unsigned int num_init_verbs;
1da177e4 310
aa563af7 311 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
312 struct hda_pcm_stream *stream_analog_playback;
313 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
314 struct hda_pcm_stream *stream_analog_alt_playback;
315 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 316
aa563af7 317 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
318 struct hda_pcm_stream *stream_digital_playback;
319 struct hda_pcm_stream *stream_digital_capture;
320
321 /* playback */
16ded525
TI
322 struct hda_multi_out multiout; /* playback set-up
323 * max_channels, dacs must be set
324 * dig_out_nid and hp_nid are optional
325 */
6330079f 326 hda_nid_t alt_dac_nid;
6a05ac4a 327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 328 int dig_out_type;
1da177e4
LT
329
330 /* capture */
331 unsigned int num_adc_nids;
332 hda_nid_t *adc_nids;
e1406348 333 hda_nid_t *capsrc_nids;
16ded525 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 335
840b64c0
TI
336 /* capture setup for dynamic dual-adc switch */
337 unsigned int cur_adc_idx;
338 hda_nid_t cur_adc;
339 unsigned int cur_adc_stream_tag;
340 unsigned int cur_adc_format;
341
1da177e4 342 /* capture source */
a1e8d2da 343 unsigned int num_mux_defs;
1da177e4
LT
344 const struct hda_input_mux *input_mux;
345 unsigned int cur_mux[3];
6c819492
TI
346 struct alc_mic_route ext_mic;
347 struct alc_mic_route int_mic;
1da177e4
LT
348
349 /* channel model */
d2a6d7dc 350 const struct hda_channel_mode *channel_mode;
1da177e4 351 int num_channel_mode;
4e195a7b 352 int need_dac_fix;
3b315d70
HM
353 int const_channel_count;
354 int ext_channel_count;
1da177e4
LT
355
356 /* PCM information */
4c5186ed 357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 358
e9edcee0
TI
359 /* dynamic controls, init_verbs and input_mux */
360 struct auto_pin_cfg autocfg;
da00c244 361 struct alc_customize_define cdefine;
603c4019 362 struct snd_array kctls;
61b9b9b1 363 struct hda_input_mux private_imux[3];
41923e44 364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 367
ae6b813a
TI
368 /* hooks */
369 void (*init_hook)(struct hda_codec *codec);
370 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 371#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 372 void (*power_hook)(struct hda_codec *codec);
f5de24b0 373#endif
ae6b813a 374
834be88d
TI
375 /* for pin sensing */
376 unsigned int sense_updated: 1;
377 unsigned int jack_present: 1;
bec15c3a 378 unsigned int master_sw: 1;
6c819492 379 unsigned int auto_mic:1;
cb53c626 380
e64f14f4
TI
381 /* other flags */
382 unsigned int no_analog :1; /* digital I/O only */
840b64c0 383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 384 int init_amp;
e64f14f4 385
2134ea4f
TI
386 /* for virtual master */
387 hda_nid_t vmaster_nid;
cb53c626
TI
388#ifdef CONFIG_SND_HDA_POWER_SAVE
389 struct hda_loopback_check loopback;
390#endif
2c3bf9ab
TI
391
392 /* for PLL fix */
393 hda_nid_t pll_nid;
394 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
395};
396
397/*
398 * configuration template - to be copied to the spec instance
399 */
400struct alc_config_preset {
9c7f852e
TI
401 struct snd_kcontrol_new *mixers[5]; /* should be identical size
402 * with spec
403 */
f9e336f6 404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
405 const struct hda_verb *init_verbs[5];
406 unsigned int num_dacs;
407 hda_nid_t *dac_nids;
408 hda_nid_t dig_out_nid; /* optional */
409 hda_nid_t hp_nid; /* optional */
b25c9da1 410 hda_nid_t *slave_dig_outs;
df694daa
KY
411 unsigned int num_adc_nids;
412 hda_nid_t *adc_nids;
e1406348 413 hda_nid_t *capsrc_nids;
df694daa
KY
414 hda_nid_t dig_in_nid;
415 unsigned int num_channel_mode;
416 const struct hda_channel_mode *channel_mode;
4e195a7b 417 int need_dac_fix;
3b315d70 418 int const_channel_count;
a1e8d2da 419 unsigned int num_mux_defs;
df694daa 420 const struct hda_input_mux *input_mux;
ae6b813a 421 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 422 void (*setup)(struct hda_codec *);
ae6b813a 423 void (*init_hook)(struct hda_codec *);
cb53c626
TI
424#ifdef CONFIG_SND_HDA_POWER_SAVE
425 struct hda_amp_list *loopbacks;
c97259df 426 void (*power_hook)(struct hda_codec *codec);
cb53c626 427#endif
1da177e4
LT
428};
429
1da177e4
LT
430
431/*
432 * input MUX handling
433 */
9c7f852e
TI
434static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
435 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
436{
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
440 if (mux_idx >= spec->num_mux_defs)
441 mux_idx = 0;
5311114d
TI
442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
443 mux_idx = 0;
a1e8d2da 444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
445}
446
9c7f852e
TI
447static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
449{
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
453
454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
455 return 0;
456}
457
9c7f852e
TI
458static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
460{
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
cd896c33 463 const struct hda_input_mux *imux;
1da177e4 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 465 unsigned int mux_idx;
e1406348
TI
466 hda_nid_t nid = spec->capsrc_nids ?
467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 468 unsigned int type;
1da177e4 469
cd896c33
TI
470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
471 imux = &spec->input_mux[mux_idx];
5311114d
TI
472 if (!imux->num_items && mux_idx > 0)
473 imux = &spec->input_mux[0];
cd896c33 474
a22d543a 475 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 476 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
477 /* Matrix-mixer style (e.g. ALC882) */
478 unsigned int *cur_val = &spec->cur_mux[adc_idx];
479 unsigned int i, idx;
480
481 idx = ucontrol->value.enumerated.item[0];
482 if (idx >= imux->num_items)
483 idx = imux->num_items - 1;
484 if (*cur_val == idx)
485 return 0;
486 for (i = 0; i < imux->num_items; i++) {
487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
489 imux->items[i].index,
490 HDA_AMP_MUTE, v);
491 }
492 *cur_val = idx;
493 return 1;
494 } else {
495 /* MUX style (e.g. ALC880) */
cd896c33 496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
497 &spec->cur_mux[adc_idx]);
498 }
499}
e9edcee0 500
1da177e4
LT
501/*
502 * channel mode setting
503 */
9c7f852e
TI
504static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
506{
507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
510 spec->num_channel_mode);
1da177e4
LT
511}
512
9c7f852e
TI
513static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
515{
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 struct alc_spec *spec = codec->spec;
d2a6d7dc 518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 519 spec->num_channel_mode,
3b315d70 520 spec->ext_channel_count);
1da177e4
LT
521}
522
9c7f852e
TI
523static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
4e195a7b
TI
528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
529 spec->num_channel_mode,
3b315d70
HM
530 &spec->ext_channel_count);
531 if (err >= 0 && !spec->const_channel_count) {
532 spec->multiout.max_channels = spec->ext_channel_count;
533 if (spec->need_dac_fix)
534 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
535 }
4e195a7b 536 return err;
1da177e4
LT
537}
538
a9430dd8 539/*
4c5186ed 540 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 541 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
542 * being part of a format specifier. Maximum allowed length of a value is
543 * 63 characters plus NULL terminator.
7cf51e48
JW
544 *
545 * Note: some retasking pin complexes seem to ignore requests for input
546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
547 * are requested. Therefore order this list so that this behaviour will not
548 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
550 * March 2006.
4c5186ed
JW
551 */
552static char *alc_pin_mode_names[] = {
7cf51e48
JW
553 "Mic 50pc bias", "Mic 80pc bias",
554 "Line in", "Line out", "Headphone out",
4c5186ed
JW
555};
556static unsigned char alc_pin_mode_values[] = {
7cf51e48 557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
558};
559/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
560 * in the pin being assumed to be exclusively an input or an output pin. In
561 * addition, "input" pins may or may not process the mic bias option
562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
563 * accept requests for bias as of chip versions up to March 2006) and/or
564 * wiring in the computer.
a9430dd8 565 */
a1e8d2da
JW
566#define ALC_PIN_DIR_IN 0x00
567#define ALC_PIN_DIR_OUT 0x01
568#define ALC_PIN_DIR_INOUT 0x02
569#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
570#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 571
ea1fb29a 572/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
573 * For each direction the minimum and maximum values are given.
574 */
a1e8d2da 575static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
576 { 0, 2 }, /* ALC_PIN_DIR_IN */
577 { 3, 4 }, /* ALC_PIN_DIR_OUT */
578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
581};
582#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
583#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
584#define alc_pin_mode_n_items(_dir) \
585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
586
9c7f852e
TI
587static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_info *uinfo)
a9430dd8 589{
4c5186ed
JW
590 unsigned int item_num = uinfo->value.enumerated.item;
591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
592
593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 594 uinfo->count = 1;
4c5186ed
JW
595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
596
597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
598 item_num = alc_pin_mode_min(dir);
599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
600 return 0;
601}
602
9c7f852e
TI
603static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
a9430dd8 605{
4c5186ed 606 unsigned int i;
a9430dd8
JW
607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
608 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 610 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
612 AC_VERB_GET_PIN_WIDGET_CONTROL,
613 0x00);
a9430dd8 614
4c5186ed
JW
615 /* Find enumerated value for current pinctl setting */
616 i = alc_pin_mode_min(dir);
4b35d2ca 617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 618 i++;
9c7f852e 619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
620 return 0;
621}
622
9c7f852e
TI
623static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
a9430dd8 625{
4c5186ed 626 signed int change;
a9430dd8
JW
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630 long val = *ucontrol->value.integer.value;
9c7f852e
TI
631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
632 AC_VERB_GET_PIN_WIDGET_CONTROL,
633 0x00);
a9430dd8 634
f12ab1e0 635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
636 val = alc_pin_mode_min(dir);
637
638 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
639 if (change) {
640 /* Set pin mode to that requested */
82beb8fd
TI
641 snd_hda_codec_write_cache(codec, nid, 0,
642 AC_VERB_SET_PIN_WIDGET_CONTROL,
643 alc_pin_mode_values[val]);
cdcd9268 644
ea1fb29a 645 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
646 * for the requested pin mode. Enum values of 2 or less are
647 * input modes.
648 *
649 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
650 * reduces noise slightly (particularly on input) so we'll
651 * do it. However, having both input and output buffers
652 * enabled simultaneously doesn't seem to be problematic if
653 * this turns out to be necessary in the future.
cdcd9268
JW
654 */
655 if (val <= 2) {
47fd830a
TI
656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
657 HDA_AMP_MUTE, HDA_AMP_MUTE);
658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
659 HDA_AMP_MUTE, 0);
cdcd9268 660 } else {
47fd830a
TI
661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
662 HDA_AMP_MUTE, HDA_AMP_MUTE);
663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
664 HDA_AMP_MUTE, 0);
cdcd9268
JW
665 }
666 }
a9430dd8
JW
667 return change;
668}
669
4c5186ed 670#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
673 .info = alc_pin_mode_info, \
674 .get = alc_pin_mode_get, \
675 .put = alc_pin_mode_put, \
676 .private_value = nid | (dir<<16) }
df694daa 677
5c8f858d
JW
678/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
679 * together using a mask with more than one bit set. This control is
680 * currently used only by the ALC260 test model. At this stage they are not
681 * needed for any "production" models.
682 */
683#ifdef CONFIG_SND_DEBUG
a5ce8890 684#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 685
9c7f852e
TI
686static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
688{
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 hda_nid_t nid = kcontrol->private_value & 0xffff;
691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
692 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
693 unsigned int val = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
695
696 *valp = (val & mask) != 0;
697 return 0;
698}
9c7f852e
TI
699static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
701{
702 signed int change;
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long val = *ucontrol->value.integer.value;
9c7f852e
TI
707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_GPIO_DATA,
709 0x00);
5c8f858d
JW
710
711 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
712 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
713 if (val == 0)
5c8f858d
JW
714 gpio_data &= ~mask;
715 else
716 gpio_data |= mask;
82beb8fd
TI
717 snd_hda_codec_write_cache(codec, nid, 0,
718 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
719
720 return change;
721}
722#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
725 .info = alc_gpio_data_info, \
726 .get = alc_gpio_data_get, \
727 .put = alc_gpio_data_put, \
728 .private_value = nid | (mask<<16) }
729#endif /* CONFIG_SND_DEBUG */
730
92621f13
JW
731/* A switch control to allow the enabling of the digital IO pins on the
732 * ALC260. This is incredibly simplistic; the intention of this control is
733 * to provide something in the test model allowing digital outputs to be
734 * identified if present. If models are found which can utilise these
735 * outputs a more complete mixer control can be devised for those models if
736 * necessary.
737 */
738#ifdef CONFIG_SND_DEBUG
a5ce8890 739#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 740
9c7f852e
TI
741static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
743{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 hda_nid_t nid = kcontrol->private_value & 0xffff;
746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
747 long *valp = ucontrol->value.integer.value;
9c7f852e 748 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 749 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
750
751 *valp = (val & mask) != 0;
752 return 0;
753}
9c7f852e
TI
754static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
756{
757 signed int change;
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long val = *ucontrol->value.integer.value;
9c7f852e 762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 763 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 764 0x00);
92621f13
JW
765
766 /* Set/unset the masked control bit(s) as needed */
9c7f852e 767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
768 if (val==0)
769 ctrl_data &= ~mask;
770 else
771 ctrl_data |= mask;
82beb8fd
TI
772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
773 ctrl_data);
92621f13
JW
774
775 return change;
776}
777#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
780 .info = alc_spdif_ctrl_info, \
781 .get = alc_spdif_ctrl_get, \
782 .put = alc_spdif_ctrl_put, \
783 .private_value = nid | (mask<<16) }
784#endif /* CONFIG_SND_DEBUG */
785
f8225f6d
JW
786/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
787 * Again, this is only used in the ALC26x test models to help identify when
788 * the EAPD line must be asserted for features to work.
789 */
790#ifdef CONFIG_SND_DEBUG
791#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
792
793static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
795{
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 *valp = ucontrol->value.integer.value;
800 unsigned int val = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
802
803 *valp = (val & mask) != 0;
804 return 0;
805}
806
807static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
808 struct snd_ctl_elem_value *ucontrol)
809{
810 int change;
811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
812 hda_nid_t nid = kcontrol->private_value & 0xffff;
813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
814 long val = *ucontrol->value.integer.value;
815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
816 AC_VERB_GET_EAPD_BTLENABLE,
817 0x00);
818
819 /* Set/unset the masked control bit(s) as needed */
820 change = (!val ? 0 : mask) != (ctrl_data & mask);
821 if (!val)
822 ctrl_data &= ~mask;
823 else
824 ctrl_data |= mask;
825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
826 ctrl_data);
827
828 return change;
829}
830
831#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
834 .info = alc_eapd_ctrl_info, \
835 .get = alc_eapd_ctrl_get, \
836 .put = alc_eapd_ctrl_put, \
837 .private_value = nid | (mask<<16) }
838#endif /* CONFIG_SND_DEBUG */
839
23f0c048
TI
840/*
841 * set up the input pin config (depending on the given auto-pin type)
842 */
843static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
844 int auto_pin_type)
845{
846 unsigned int val = PIN_IN;
847
848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
849 unsigned int pincap;
1327a32b 850 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
851 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
852 if (pincap & AC_PINCAP_VREF_80)
853 val = PIN_VREF80;
461c6c3a
TI
854 else if (pincap & AC_PINCAP_VREF_50)
855 val = PIN_VREF50;
856 else if (pincap & AC_PINCAP_VREF_100)
857 val = PIN_VREF100;
858 else if (pincap & AC_PINCAP_VREF_GRD)
859 val = PIN_VREFGRD;
23f0c048
TI
860 }
861 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
862}
863
d88897ea
TI
864/*
865 */
866static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
867{
868 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
869 return;
870 spec->mixers[spec->num_mixers++] = mix;
871}
872
873static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
874{
875 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
876 return;
877 spec->init_verbs[spec->num_init_verbs++] = verb;
878}
879
df694daa
KY
880/*
881 * set up from the preset table
882 */
e9c364c0 883static void setup_preset(struct hda_codec *codec,
9c7f852e 884 const struct alc_config_preset *preset)
df694daa 885{
e9c364c0 886 struct alc_spec *spec = codec->spec;
df694daa
KY
887 int i;
888
889 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 890 add_mixer(spec, preset->mixers[i]);
f9e336f6 891 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
892 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
893 i++)
d88897ea 894 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 895
df694daa
KY
896 spec->channel_mode = preset->channel_mode;
897 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 898 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 899 spec->const_channel_count = preset->const_channel_count;
df694daa 900
3b315d70
HM
901 if (preset->const_channel_count)
902 spec->multiout.max_channels = preset->const_channel_count;
903 else
904 spec->multiout.max_channels = spec->channel_mode[0].channels;
905 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
906
907 spec->multiout.num_dacs = preset->num_dacs;
908 spec->multiout.dac_nids = preset->dac_nids;
909 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 910 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 911 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 912
a1e8d2da 913 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 914 if (!spec->num_mux_defs)
a1e8d2da 915 spec->num_mux_defs = 1;
df694daa
KY
916 spec->input_mux = preset->input_mux;
917
918 spec->num_adc_nids = preset->num_adc_nids;
919 spec->adc_nids = preset->adc_nids;
e1406348 920 spec->capsrc_nids = preset->capsrc_nids;
df694daa 921 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
922
923 spec->unsol_event = preset->unsol_event;
924 spec->init_hook = preset->init_hook;
cb53c626 925#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 926 spec->power_hook = preset->power_hook;
cb53c626
TI
927 spec->loopback.amplist = preset->loopbacks;
928#endif
e9c364c0
TI
929
930 if (preset->setup)
931 preset->setup(codec);
df694daa
KY
932}
933
bc9f98a9
KY
934/* Enable GPIO mask and set output */
935static struct hda_verb alc_gpio1_init_verbs[] = {
936 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
937 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
938 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
939 { }
940};
941
942static struct hda_verb alc_gpio2_init_verbs[] = {
943 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
944 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
945 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
946 { }
947};
948
bdd148a3
KY
949static struct hda_verb alc_gpio3_init_verbs[] = {
950 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
951 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
952 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
953 { }
954};
955
2c3bf9ab
TI
956/*
957 * Fix hardware PLL issue
958 * On some codecs, the analog PLL gating control must be off while
959 * the default value is 1.
960 */
961static void alc_fix_pll(struct hda_codec *codec)
962{
963 struct alc_spec *spec = codec->spec;
964 unsigned int val;
965
966 if (!spec->pll_nid)
967 return;
968 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
969 spec->pll_coef_idx);
970 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
971 AC_VERB_GET_PROC_COEF, 0);
972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
973 spec->pll_coef_idx);
974 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
975 val & ~(1 << spec->pll_coef_bit));
976}
977
978static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
979 unsigned int coef_idx, unsigned int coef_bit)
980{
981 struct alc_spec *spec = codec->spec;
982 spec->pll_nid = nid;
983 spec->pll_coef_idx = coef_idx;
984 spec->pll_coef_bit = coef_bit;
985 alc_fix_pll(codec);
986}
987
a9fd4f3f 988static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
989{
990 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
991 unsigned int nid = spec->autocfg.hp_pins[0];
992 int i;
c9b58006 993
ad87c64f
TI
994 if (!nid)
995 return;
864f92be 996 spec->jack_present = snd_hda_jack_detect(codec, nid);
a9fd4f3f
TI
997 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
998 nid = spec->autocfg.speaker_pins[i];
999 if (!nid)
1000 break;
1001 snd_hda_codec_write(codec, nid, 0,
1002 AC_VERB_SET_PIN_WIDGET_CONTROL,
1003 spec->jack_present ? 0 : PIN_OUT);
1004 }
c9b58006
KY
1005}
1006
6c819492
TI
1007static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1008 hda_nid_t nid)
1009{
1010 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1011 int i, nums;
1012
1013 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1014 for (i = 0; i < nums; i++)
1015 if (conn[i] == nid)
1016 return i;
1017 return -1;
1018}
1019
840b64c0
TI
1020/* switch the current ADC according to the jack state */
1021static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1022{
1023 struct alc_spec *spec = codec->spec;
1024 unsigned int present;
1025 hda_nid_t new_adc;
1026
1027 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1028 if (present)
1029 spec->cur_adc_idx = 1;
1030 else
1031 spec->cur_adc_idx = 0;
1032 new_adc = spec->adc_nids[spec->cur_adc_idx];
1033 if (spec->cur_adc && spec->cur_adc != new_adc) {
1034 /* stream is running, let's swap the current ADC */
1035 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1036 spec->cur_adc = new_adc;
1037 snd_hda_codec_setup_stream(codec, new_adc,
1038 spec->cur_adc_stream_tag, 0,
1039 spec->cur_adc_format);
1040 }
1041}
1042
7fb0d78f
KY
1043static void alc_mic_automute(struct hda_codec *codec)
1044{
1045 struct alc_spec *spec = codec->spec;
6c819492
TI
1046 struct alc_mic_route *dead, *alive;
1047 unsigned int present, type;
1048 hda_nid_t cap_nid;
1049
b59bdf3b
TI
1050 if (!spec->auto_mic)
1051 return;
6c819492
TI
1052 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1053 return;
1054 if (snd_BUG_ON(!spec->adc_nids))
1055 return;
1056
840b64c0
TI
1057 if (spec->dual_adc_switch) {
1058 alc_dual_mic_adc_auto_switch(codec);
1059 return;
1060 }
1061
6c819492
TI
1062 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1063
864f92be 1064 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1065 if (present) {
1066 alive = &spec->ext_mic;
1067 dead = &spec->int_mic;
1068 } else {
1069 alive = &spec->int_mic;
1070 dead = &spec->ext_mic;
1071 }
1072
6c819492
TI
1073 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1074 if (type == AC_WID_AUD_MIX) {
1075 /* Matrix-mixer style (e.g. ALC882) */
1076 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1077 alive->mux_idx,
1078 HDA_AMP_MUTE, 0);
1079 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1080 dead->mux_idx,
1081 HDA_AMP_MUTE, HDA_AMP_MUTE);
1082 } else {
1083 /* MUX style (e.g. ALC880) */
1084 snd_hda_codec_write_cache(codec, cap_nid, 0,
1085 AC_VERB_SET_CONNECT_SEL,
1086 alive->mux_idx);
1087 }
1088
1089 /* FIXME: analog mixer */
7fb0d78f
KY
1090}
1091
c9b58006
KY
1092/* unsolicited event for HP jack sensing */
1093static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1094{
1095 if (codec->vendor_id == 0x10ec0880)
1096 res >>= 28;
1097 else
1098 res >>= 26;
a9fd4f3f
TI
1099 switch (res) {
1100 case ALC880_HP_EVENT:
1101 alc_automute_pin(codec);
1102 break;
1103 case ALC880_MIC_EVENT:
7fb0d78f 1104 alc_mic_automute(codec);
a9fd4f3f
TI
1105 break;
1106 }
7fb0d78f
KY
1107}
1108
1109static void alc_inithook(struct hda_codec *codec)
1110{
a9fd4f3f 1111 alc_automute_pin(codec);
7fb0d78f 1112 alc_mic_automute(codec);
c9b58006
KY
1113}
1114
f9423e7a
KY
1115/* additional initialization for ALC888 variants */
1116static void alc888_coef_init(struct hda_codec *codec)
1117{
1118 unsigned int tmp;
1119
1120 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1121 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1122 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1123 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1124 /* alc888S-VC */
1125 snd_hda_codec_read(codec, 0x20, 0,
1126 AC_VERB_SET_PROC_COEF, 0x830);
1127 else
1128 /* alc888-VB */
1129 snd_hda_codec_read(codec, 0x20, 0,
1130 AC_VERB_SET_PROC_COEF, 0x3030);
1131}
1132
87a8c370
JK
1133static void alc889_coef_init(struct hda_codec *codec)
1134{
1135 unsigned int tmp;
1136
1137 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1138 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1139 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1140 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1141}
1142
3fb4a508
TI
1143/* turn on/off EAPD control (only if available) */
1144static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1145{
1146 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1147 return;
1148 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1150 on ? 2 : 0);
1151}
1152
4a79ba34 1153static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1154{
4a79ba34 1155 unsigned int tmp;
bc9f98a9 1156
4a79ba34
TI
1157 switch (type) {
1158 case ALC_INIT_GPIO1:
bc9f98a9
KY
1159 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1160 break;
4a79ba34 1161 case ALC_INIT_GPIO2:
bc9f98a9
KY
1162 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1163 break;
4a79ba34 1164 case ALC_INIT_GPIO3:
bdd148a3
KY
1165 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1166 break;
4a79ba34 1167 case ALC_INIT_DEFAULT:
bdd148a3 1168 switch (codec->vendor_id) {
c9b58006 1169 case 0x10ec0260:
3fb4a508
TI
1170 set_eapd(codec, 0x0f, 1);
1171 set_eapd(codec, 0x10, 1);
c9b58006
KY
1172 break;
1173 case 0x10ec0262:
bdd148a3
KY
1174 case 0x10ec0267:
1175 case 0x10ec0268:
c9b58006 1176 case 0x10ec0269:
3fb4a508 1177 case 0x10ec0270:
c6e8f2da 1178 case 0x10ec0272:
f9423e7a
KY
1179 case 0x10ec0660:
1180 case 0x10ec0662:
1181 case 0x10ec0663:
c9b58006 1182 case 0x10ec0862:
20a3a05d 1183 case 0x10ec0889:
3fb4a508
TI
1184 set_eapd(codec, 0x14, 1);
1185 set_eapd(codec, 0x15, 1);
c9b58006 1186 break;
bdd148a3 1187 }
c9b58006
KY
1188 switch (codec->vendor_id) {
1189 case 0x10ec0260:
1190 snd_hda_codec_write(codec, 0x1a, 0,
1191 AC_VERB_SET_COEF_INDEX, 7);
1192 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1193 AC_VERB_GET_PROC_COEF, 0);
1194 snd_hda_codec_write(codec, 0x1a, 0,
1195 AC_VERB_SET_COEF_INDEX, 7);
1196 snd_hda_codec_write(codec, 0x1a, 0,
1197 AC_VERB_SET_PROC_COEF,
1198 tmp | 0x2010);
1199 break;
1200 case 0x10ec0262:
1201 case 0x10ec0880:
1202 case 0x10ec0882:
1203 case 0x10ec0883:
1204 case 0x10ec0885:
4a5a4c56 1205 case 0x10ec0887:
20a3a05d 1206 case 0x10ec0889:
87a8c370 1207 alc889_coef_init(codec);
c9b58006 1208 break;
f9423e7a 1209 case 0x10ec0888:
4a79ba34 1210 alc888_coef_init(codec);
f9423e7a 1211 break;
0aea778e 1212#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1213 case 0x10ec0267:
1214 case 0x10ec0268:
1215 snd_hda_codec_write(codec, 0x20, 0,
1216 AC_VERB_SET_COEF_INDEX, 7);
1217 tmp = snd_hda_codec_read(codec, 0x20, 0,
1218 AC_VERB_GET_PROC_COEF, 0);
1219 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1220 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1221 snd_hda_codec_write(codec, 0x20, 0,
1222 AC_VERB_SET_PROC_COEF,
1223 tmp | 0x3000);
1224 break;
0aea778e 1225#endif /* XXX */
bc9f98a9 1226 }
4a79ba34
TI
1227 break;
1228 }
1229}
1230
1231static void alc_init_auto_hp(struct hda_codec *codec)
1232{
1233 struct alc_spec *spec = codec->spec;
1234
1235 if (!spec->autocfg.hp_pins[0])
1236 return;
1237
1238 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1239 if (spec->autocfg.line_out_pins[0] &&
1240 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1241 spec->autocfg.speaker_pins[0] =
1242 spec->autocfg.line_out_pins[0];
1243 else
1244 return;
1245 }
1246
2a2ed0df
TI
1247 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1248 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1249 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1250 AC_VERB_SET_UNSOLICITED_ENABLE,
1251 AC_USRSP_EN | ALC880_HP_EVENT);
1252 spec->unsol_event = alc_sku_unsol_event;
1253}
1254
6c819492
TI
1255static void alc_init_auto_mic(struct hda_codec *codec)
1256{
1257 struct alc_spec *spec = codec->spec;
1258 struct auto_pin_cfg *cfg = &spec->autocfg;
1259 hda_nid_t fixed, ext;
1260 int i;
1261
1262 /* there must be only two mic inputs exclusively */
1263 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1264 if (cfg->input_pins[i])
1265 return;
1266
1267 fixed = ext = 0;
1268 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1269 hda_nid_t nid = cfg->input_pins[i];
1270 unsigned int defcfg;
1271 if (!nid)
1272 return;
1273 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1274 switch (get_defcfg_connect(defcfg)) {
1275 case AC_JACK_PORT_FIXED:
1276 if (fixed)
1277 return; /* already occupied */
1278 fixed = nid;
1279 break;
1280 case AC_JACK_PORT_COMPLEX:
1281 if (ext)
1282 return; /* already occupied */
1283 ext = nid;
1284 break;
1285 default:
1286 return; /* invalid entry */
1287 }
1288 }
eaa9b3a7
TI
1289 if (!ext || !fixed)
1290 return;
6c819492
TI
1291 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1292 return; /* no unsol support */
1293 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1294 ext, fixed);
1295 spec->ext_mic.pin = ext;
1296 spec->int_mic.pin = fixed;
1297 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1298 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1299 spec->auto_mic = 1;
1300 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1301 AC_VERB_SET_UNSOLICITED_ENABLE,
1302 AC_USRSP_EN | ALC880_MIC_EVENT);
1303 spec->unsol_event = alc_sku_unsol_event;
1304}
1305
da00c244
KY
1306static int alc_auto_parse_customize_define(struct hda_codec *codec)
1307{
1308 unsigned int ass, tmp, i;
7fb56223 1309 unsigned nid = 0;
da00c244
KY
1310 struct alc_spec *spec = codec->spec;
1311
b6cbe517
TI
1312 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1313
da00c244 1314 ass = codec->subsystem_id & 0xffff;
b6cbe517 1315 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1316 goto do_sku;
1317
1318 nid = 0x1d;
1319 if (codec->vendor_id == 0x10ec0260)
1320 nid = 0x17;
1321 ass = snd_hda_codec_get_pincfg(codec, nid);
1322
1323 if (!(ass & 1)) {
1324 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1325 codec->chip_name, ass);
1326 return -1;
1327 }
1328
1329 /* check sum */
1330 tmp = 0;
1331 for (i = 1; i < 16; i++) {
1332 if ((ass >> i) & 1)
1333 tmp++;
1334 }
1335 if (((ass >> 16) & 0xf) != tmp)
1336 return -1;
1337
1338 spec->cdefine.port_connectivity = ass >> 30;
1339 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1340 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1341 spec->cdefine.customization = ass >> 8;
1342do_sku:
1343 spec->cdefine.sku_cfg = ass;
1344 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1345 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1346 spec->cdefine.swap = (ass & 0x2) >> 1;
1347 spec->cdefine.override = ass & 0x1;
1348
1349 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1350 nid, spec->cdefine.sku_cfg);
1351 snd_printd("SKU: port_connectivity=0x%x\n",
1352 spec->cdefine.port_connectivity);
1353 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1354 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1355 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1356 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1357 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1358 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1359 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1360
1361 return 0;
1362}
1363
4a79ba34
TI
1364/* check subsystem ID and set up device-specific initialization;
1365 * return 1 if initialized, 0 if invalid SSID
1366 */
1367/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1368 * 31 ~ 16 : Manufacture ID
1369 * 15 ~ 8 : SKU ID
1370 * 7 ~ 0 : Assembly ID
1371 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1372 */
1373static int alc_subsystem_id(struct hda_codec *codec,
1374 hda_nid_t porta, hda_nid_t porte,
6227cdce 1375 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1376{
1377 unsigned int ass, tmp, i;
1378 unsigned nid;
1379 struct alc_spec *spec = codec->spec;
1380
1381 ass = codec->subsystem_id & 0xffff;
1382 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1383 goto do_sku;
1384
1385 /* invalid SSID, check the special NID pin defcfg instead */
1386 /*
def319f9 1387 * 31~30 : port connectivity
4a79ba34
TI
1388 * 29~21 : reserve
1389 * 20 : PCBEEP input
1390 * 19~16 : Check sum (15:1)
1391 * 15~1 : Custom
1392 * 0 : override
1393 */
1394 nid = 0x1d;
1395 if (codec->vendor_id == 0x10ec0260)
1396 nid = 0x17;
1397 ass = snd_hda_codec_get_pincfg(codec, nid);
1398 snd_printd("realtek: No valid SSID, "
1399 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1400 ass, nid);
6227cdce 1401 if (!(ass & 1))
4a79ba34
TI
1402 return 0;
1403 if ((ass >> 30) != 1) /* no physical connection */
1404 return 0;
1405
1406 /* check sum */
1407 tmp = 0;
1408 for (i = 1; i < 16; i++) {
1409 if ((ass >> i) & 1)
1410 tmp++;
1411 }
1412 if (((ass >> 16) & 0xf) != tmp)
1413 return 0;
1414do_sku:
1415 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1416 ass & 0xffff, codec->vendor_id);
1417 /*
1418 * 0 : override
1419 * 1 : Swap Jack
1420 * 2 : 0 --> Desktop, 1 --> Laptop
1421 * 3~5 : External Amplifier control
1422 * 7~6 : Reserved
1423 */
1424 tmp = (ass & 0x38) >> 3; /* external Amp control */
1425 switch (tmp) {
1426 case 1:
1427 spec->init_amp = ALC_INIT_GPIO1;
1428 break;
1429 case 3:
1430 spec->init_amp = ALC_INIT_GPIO2;
1431 break;
1432 case 7:
1433 spec->init_amp = ALC_INIT_GPIO3;
1434 break;
1435 case 5:
1436 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1437 break;
1438 }
ea1fb29a 1439
8c427226 1440 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1441 * when the external headphone out jack is plugged"
1442 */
8c427226 1443 if (!(ass & 0x8000))
4a79ba34 1444 return 1;
c9b58006
KY
1445 /*
1446 * 10~8 : Jack location
1447 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1448 * 14~13: Resvered
1449 * 15 : 1 --> enable the function "Mute internal speaker
1450 * when the external headphone out jack is plugged"
1451 */
c9b58006 1452 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1453 hda_nid_t nid;
c9b58006
KY
1454 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1455 if (tmp == 0)
01d4825d 1456 nid = porta;
c9b58006 1457 else if (tmp == 1)
01d4825d 1458 nid = porte;
c9b58006 1459 else if (tmp == 2)
01d4825d 1460 nid = portd;
6227cdce
KY
1461 else if (tmp == 3)
1462 nid = porti;
c9b58006 1463 else
4a79ba34 1464 return 1;
01d4825d
TI
1465 for (i = 0; i < spec->autocfg.line_outs; i++)
1466 if (spec->autocfg.line_out_pins[i] == nid)
1467 return 1;
1468 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1469 }
1470
4a79ba34 1471 alc_init_auto_hp(codec);
6c819492 1472 alc_init_auto_mic(codec);
4a79ba34
TI
1473 return 1;
1474}
ea1fb29a 1475
4a79ba34 1476static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1477 hda_nid_t porta, hda_nid_t porte,
1478 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1479{
6227cdce 1480 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1481 struct alc_spec *spec = codec->spec;
1482 snd_printd("realtek: "
1483 "Enable default setup for auto mode as fallback\n");
1484 spec->init_amp = ALC_INIT_DEFAULT;
1485 alc_init_auto_hp(codec);
6c819492 1486 alc_init_auto_mic(codec);
4a79ba34 1487 }
bc9f98a9
KY
1488}
1489
f95474ec 1490/*
f8f25ba3 1491 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1492 */
1493
1494struct alc_pincfg {
1495 hda_nid_t nid;
1496 u32 val;
1497};
1498
f8f25ba3
TI
1499struct alc_fixup {
1500 const struct alc_pincfg *pins;
1501 const struct hda_verb *verbs;
1502};
1503
1504static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1505 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1506 const struct alc_fixup *fix,
1507 int pre_init)
f95474ec
TI
1508{
1509 const struct alc_pincfg *cfg;
1510
1511 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1512 if (!quirk)
1513 return;
f8f25ba3
TI
1514 fix += quirk->value;
1515 cfg = fix->pins;
7fa90e87
TI
1516 if (pre_init && cfg) {
1517#ifdef CONFIG_SND_DEBUG_VERBOSE
1518 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1519 codec->chip_name, quirk->name);
1520#endif
f8f25ba3
TI
1521 for (; cfg->nid; cfg++)
1522 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1523 }
7fa90e87
TI
1524 if (!pre_init && fix->verbs) {
1525#ifdef CONFIG_SND_DEBUG_VERBOSE
1526 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1527 codec->chip_name, quirk->name);
1528#endif
f8f25ba3 1529 add_verb(codec->spec, fix->verbs);
7fa90e87 1530 }
f95474ec
TI
1531}
1532
274693f3
KY
1533static int alc_read_coef_idx(struct hda_codec *codec,
1534 unsigned int coef_idx)
1535{
1536 unsigned int val;
1537 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1538 coef_idx);
1539 val = snd_hda_codec_read(codec, 0x20, 0,
1540 AC_VERB_GET_PROC_COEF, 0);
1541 return val;
1542}
1543
ef8ef5fb
VP
1544/*
1545 * ALC888
1546 */
1547
1548/*
1549 * 2ch mode
1550 */
1551static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1552/* Mic-in jack as mic in */
1553 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1554 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1555/* Line-in jack as Line in */
1556 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1557 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1558/* Line-Out as Front */
1559 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1560 { } /* end */
1561};
1562
1563/*
1564 * 4ch mode
1565 */
1566static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1567/* Mic-in jack as mic in */
1568 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1569 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1570/* Line-in jack as Surround */
1571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1573/* Line-Out as Front */
1574 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1575 { } /* end */
1576};
1577
1578/*
1579 * 6ch mode
1580 */
1581static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1582/* Mic-in jack as CLFE */
1583 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1584 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1585/* Line-in jack as Surround */
1586 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1587 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1588/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1589 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1590 { } /* end */
1591};
1592
1593/*
1594 * 8ch mode
1595 */
1596static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1597/* Mic-in jack as CLFE */
1598 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1599 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1600/* Line-in jack as Surround */
1601 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1602 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1603/* Line-Out as Side */
1604 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1605 { } /* end */
1606};
1607
1608static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1609 { 2, alc888_4ST_ch2_intel_init },
1610 { 4, alc888_4ST_ch4_intel_init },
1611 { 6, alc888_4ST_ch6_intel_init },
1612 { 8, alc888_4ST_ch8_intel_init },
1613};
1614
1615/*
1616 * ALC888 Fujitsu Siemens Amillo xa3530
1617 */
1618
1619static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1620/* Front Mic: set to PIN_IN (empty by default) */
1621 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1622/* Connect Internal HP to Front */
1623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1625 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1626/* Connect Bass HP to Front */
1627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1628 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1629 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1630/* Connect Line-Out side jack (SPDIF) to Side */
1631 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1632 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1633 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1634/* Connect Mic jack to CLFE */
1635 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1636 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1637 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1638/* Connect Line-in jack to Surround */
1639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1640 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1641 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1642/* Connect HP out jack to Front */
1643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1644 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1645 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1646/* Enable unsolicited event for HP jack and Line-out jack */
1647 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1648 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1649 {}
1650};
1651
a9fd4f3f 1652static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1653{
a9fd4f3f 1654 struct alc_spec *spec = codec->spec;
864f92be 1655 unsigned int mute;
a9fd4f3f
TI
1656 hda_nid_t nid;
1657 int i;
1658
1659 spec->jack_present = 0;
1660 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1661 nid = spec->autocfg.hp_pins[i];
1662 if (!nid)
1663 break;
864f92be 1664 if (snd_hda_jack_detect(codec, nid)) {
a9fd4f3f
TI
1665 spec->jack_present = 1;
1666 break;
1667 }
1668 }
1669
1670 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1671 /* Toggle internal speakers muting */
a9fd4f3f
TI
1672 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1673 nid = spec->autocfg.speaker_pins[i];
1674 if (!nid)
1675 break;
1676 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1677 HDA_AMP_MUTE, mute);
1678 }
ef8ef5fb
VP
1679}
1680
a9fd4f3f
TI
1681static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1682 unsigned int res)
ef8ef5fb 1683{
a9fd4f3f
TI
1684 if (codec->vendor_id == 0x10ec0880)
1685 res >>= 28;
1686 else
1687 res >>= 26;
1688 if (res == ALC880_HP_EVENT)
1689 alc_automute_amp(codec);
ef8ef5fb
VP
1690}
1691
4f5d1706 1692static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1693{
1694 struct alc_spec *spec = codec->spec;
1695
1696 spec->autocfg.hp_pins[0] = 0x15;
1697 spec->autocfg.speaker_pins[0] = 0x14;
1698 spec->autocfg.speaker_pins[1] = 0x16;
1699 spec->autocfg.speaker_pins[2] = 0x17;
1700 spec->autocfg.speaker_pins[3] = 0x19;
1701 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1702}
1703
1704static void alc889_intel_init_hook(struct hda_codec *codec)
1705{
1706 alc889_coef_init(codec);
4f5d1706 1707 alc_automute_amp(codec);
6732bd0d
WF
1708}
1709
4f5d1706 1710static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1711{
1712 struct alc_spec *spec = codec->spec;
1713
1714 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1715 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1716 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1717 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1718}
ef8ef5fb 1719
5b2d1eca
VP
1720/*
1721 * ALC888 Acer Aspire 4930G model
1722 */
1723
1724static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1725/* Front Mic: set to PIN_IN (empty by default) */
1726 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1727/* Unselect Front Mic by default in input mixer 3 */
1728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1729/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1730 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1731/* Connect Internal HP to front */
1732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1734 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1735/* Connect HP out to front */
1736 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1737 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1738 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1739 { }
1740};
1741
d2fd4b09
TV
1742/*
1743 * ALC888 Acer Aspire 6530G model
1744 */
1745
1746static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1747/* Route to built-in subwoofer as well as speakers */
1748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1752/* Bias voltage on for external mic port */
1753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1754/* Front Mic: set to PIN_IN (empty by default) */
1755 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1756/* Unselect Front Mic by default in input mixer 3 */
1757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1758/* Enable unsolicited event for HP jack */
1759 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1760/* Enable speaker output */
1761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1762 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1763 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1764/* Enable headphone output */
1765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1767 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1768 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1769 { }
1770};
1771
3b315d70 1772/*
018df418 1773 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1774 */
1775
018df418 1776static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1777/* Front Mic: set to PIN_IN (empty by default) */
1778 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1779/* Unselect Front Mic by default in input mixer 3 */
1780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1781/* Enable unsolicited event for HP jack */
1782 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1783/* Connect Internal Front to Front */
1784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1786 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1787/* Connect Internal Rear to Rear */
1788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1790 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1791/* Connect Internal CLFE to CLFE */
1792 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1794 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1795/* Connect HP out to Front */
018df418 1796 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1799/* Enable all DACs */
1800/* DAC DISABLE/MUTE 1? */
1801/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1802 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1803 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1804/* DAC DISABLE/MUTE 2? */
1805/* some bit here disables the other DACs. Init=0x4900 */
1806 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1807 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1808/* DMIC fix
1809 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1810 * which makes the stereo useless. However, either the mic or the ALC889
1811 * makes the signal become a difference/sum signal instead of standard
1812 * stereo, which is annoying. So instead we flip this bit which makes the
1813 * codec replicate the sum signal to both channels, turning it into a
1814 * normal mono mic.
1815 */
1816/* DMIC_CONTROL? Init value = 0x0001 */
1817 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1818 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1819 { }
1820};
1821
ef8ef5fb 1822static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1823 /* Front mic only available on one ADC */
1824 {
1825 .num_items = 4,
1826 .items = {
1827 { "Mic", 0x0 },
1828 { "Line", 0x2 },
1829 { "CD", 0x4 },
1830 { "Front Mic", 0xb },
1831 },
1832 },
1833 {
1834 .num_items = 3,
1835 .items = {
1836 { "Mic", 0x0 },
1837 { "Line", 0x2 },
1838 { "CD", 0x4 },
1839 },
1840 }
1841};
1842
d2fd4b09
TV
1843static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1844 /* Interal mic only available on one ADC */
1845 {
684a8842 1846 .num_items = 5,
d2fd4b09
TV
1847 .items = {
1848 { "Ext Mic", 0x0 },
684a8842 1849 { "Line In", 0x2 },
d2fd4b09 1850 { "CD", 0x4 },
684a8842 1851 { "Input Mix", 0xa },
d2fd4b09
TV
1852 { "Int Mic", 0xb },
1853 },
1854 },
1855 {
684a8842 1856 .num_items = 4,
d2fd4b09
TV
1857 .items = {
1858 { "Ext Mic", 0x0 },
684a8842 1859 { "Line In", 0x2 },
d2fd4b09 1860 { "CD", 0x4 },
684a8842 1861 { "Input Mix", 0xa },
d2fd4b09
TV
1862 },
1863 }
1864};
1865
018df418
HM
1866static struct hda_input_mux alc889_capture_sources[3] = {
1867 /* Digital mic only available on first "ADC" */
1868 {
1869 .num_items = 5,
1870 .items = {
1871 { "Mic", 0x0 },
1872 { "Line", 0x2 },
1873 { "CD", 0x4 },
1874 { "Front Mic", 0xb },
1875 { "Input Mix", 0xa },
1876 },
1877 },
1878 {
1879 .num_items = 4,
1880 .items = {
1881 { "Mic", 0x0 },
1882 { "Line", 0x2 },
1883 { "CD", 0x4 },
1884 { "Input Mix", 0xa },
1885 },
1886 },
1887 {
1888 .num_items = 4,
1889 .items = {
1890 { "Mic", 0x0 },
1891 { "Line", 0x2 },
1892 { "CD", 0x4 },
1893 { "Input Mix", 0xa },
1894 },
1895 }
1896};
1897
ef8ef5fb 1898static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1899 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1900 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1901 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1902 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1903 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1904 HDA_OUTPUT),
1905 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1906 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1907 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1908 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1909 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1910 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1911 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1912 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1913 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1914 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1915 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1916 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1917 { } /* end */
1918};
1919
556eea9a
HM
1920static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1921 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1922 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1923 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1924 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1925 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1926 HDA_OUTPUT),
1927 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1928 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1929 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1930 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1931 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1933 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1935 { } /* end */
1936};
1937
1938
4f5d1706 1939static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 1940{
a9fd4f3f 1941 struct alc_spec *spec = codec->spec;
5b2d1eca 1942
a9fd4f3f
TI
1943 spec->autocfg.hp_pins[0] = 0x15;
1944 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
1945 spec->autocfg.speaker_pins[1] = 0x16;
1946 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
1947}
1948
4f5d1706 1949static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
1950{
1951 struct alc_spec *spec = codec->spec;
1952
1953 spec->autocfg.hp_pins[0] = 0x15;
1954 spec->autocfg.speaker_pins[0] = 0x14;
1955 spec->autocfg.speaker_pins[1] = 0x16;
1956 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
1957}
1958
4f5d1706 1959static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
1960{
1961 struct alc_spec *spec = codec->spec;
1962
1963 spec->autocfg.hp_pins[0] = 0x15;
1964 spec->autocfg.speaker_pins[0] = 0x14;
1965 spec->autocfg.speaker_pins[1] = 0x16;
1966 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
1967}
1968
1da177e4 1969/*
e9edcee0
TI
1970 * ALC880 3-stack model
1971 *
1972 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1973 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1974 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1975 */
1976
e9edcee0
TI
1977static hda_nid_t alc880_dac_nids[4] = {
1978 /* front, rear, clfe, rear_surr */
1979 0x02, 0x05, 0x04, 0x03
1980};
1981
1982static hda_nid_t alc880_adc_nids[3] = {
1983 /* ADC0-2 */
1984 0x07, 0x08, 0x09,
1985};
1986
1987/* The datasheet says the node 0x07 is connected from inputs,
1988 * but it shows zero connection in the real implementation on some devices.
df694daa 1989 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1990 */
e9edcee0
TI
1991static hda_nid_t alc880_adc_nids_alt[2] = {
1992 /* ADC1-2 */
1993 0x08, 0x09,
1994};
1995
1996#define ALC880_DIGOUT_NID 0x06
1997#define ALC880_DIGIN_NID 0x0a
1998
1999static struct hda_input_mux alc880_capture_source = {
2000 .num_items = 4,
2001 .items = {
2002 { "Mic", 0x0 },
2003 { "Front Mic", 0x3 },
2004 { "Line", 0x2 },
2005 { "CD", 0x4 },
2006 },
2007};
2008
2009/* channel source setting (2/6 channel selection for 3-stack) */
2010/* 2ch mode */
2011static struct hda_verb alc880_threestack_ch2_init[] = {
2012 /* set line-in to input, mute it */
2013 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2014 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2015 /* set mic-in to input vref 80%, mute it */
2016 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2017 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2018 { } /* end */
2019};
2020
2021/* 6ch mode */
2022static struct hda_verb alc880_threestack_ch6_init[] = {
2023 /* set line-in to output, unmute it */
2024 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2025 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2026 /* set mic-in to output, unmute it */
2027 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2028 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2029 { } /* end */
2030};
2031
d2a6d7dc 2032static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2033 { 2, alc880_threestack_ch2_init },
2034 { 6, alc880_threestack_ch6_init },
2035};
2036
c8b6bf9b 2037static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2038 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2039 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2040 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2041 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2042 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2043 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2044 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2045 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2046 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2047 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2049 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2050 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2051 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2052 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2053 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2055 {
2056 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2057 .name = "Channel Mode",
df694daa
KY
2058 .info = alc_ch_mode_info,
2059 .get = alc_ch_mode_get,
2060 .put = alc_ch_mode_put,
e9edcee0
TI
2061 },
2062 { } /* end */
2063};
2064
2065/* capture mixer elements */
f9e336f6
TI
2066static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2067 struct snd_ctl_elem_info *uinfo)
2068{
2069 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2070 struct alc_spec *spec = codec->spec;
2071 int err;
1da177e4 2072
5a9e02e9 2073 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2074 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2075 HDA_INPUT);
2076 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2077 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2078 return err;
2079}
2080
2081static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2082 unsigned int size, unsigned int __user *tlv)
2083{
2084 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2085 struct alc_spec *spec = codec->spec;
2086 int err;
1da177e4 2087
5a9e02e9 2088 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2089 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2090 HDA_INPUT);
2091 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2092 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2093 return err;
2094}
2095
2096typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2097 struct snd_ctl_elem_value *ucontrol);
2098
2099static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2100 struct snd_ctl_elem_value *ucontrol,
2101 getput_call_t func)
2102{
2103 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2104 struct alc_spec *spec = codec->spec;
2105 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2106 int err;
2107
5a9e02e9 2108 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2109 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2110 3, 0, HDA_INPUT);
2111 err = func(kcontrol, ucontrol);
5a9e02e9 2112 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2113 return err;
2114}
2115
2116static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2117 struct snd_ctl_elem_value *ucontrol)
2118{
2119 return alc_cap_getput_caller(kcontrol, ucontrol,
2120 snd_hda_mixer_amp_volume_get);
2121}
2122
2123static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2124 struct snd_ctl_elem_value *ucontrol)
2125{
2126 return alc_cap_getput_caller(kcontrol, ucontrol,
2127 snd_hda_mixer_amp_volume_put);
2128}
2129
2130/* capture mixer elements */
2131#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2132
2133static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2134 struct snd_ctl_elem_value *ucontrol)
2135{
2136 return alc_cap_getput_caller(kcontrol, ucontrol,
2137 snd_hda_mixer_amp_switch_get);
2138}
2139
2140static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2141 struct snd_ctl_elem_value *ucontrol)
2142{
2143 return alc_cap_getput_caller(kcontrol, ucontrol,
2144 snd_hda_mixer_amp_switch_put);
2145}
2146
a23b688f 2147#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2148 { \
2149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2150 .name = "Capture Switch", \
2151 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2152 .count = num, \
2153 .info = alc_cap_sw_info, \
2154 .get = alc_cap_sw_get, \
2155 .put = alc_cap_sw_put, \
2156 }, \
2157 { \
2158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2159 .name = "Capture Volume", \
2160 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2161 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2162 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2163 .count = num, \
2164 .info = alc_cap_vol_info, \
2165 .get = alc_cap_vol_get, \
2166 .put = alc_cap_vol_put, \
2167 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2168 }
2169
2170#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2171 { \
2172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2173 /* .name = "Capture Source", */ \
2174 .name = "Input Source", \
2175 .count = num, \
2176 .info = alc_mux_enum_info, \
2177 .get = alc_mux_enum_get, \
2178 .put = alc_mux_enum_put, \
a23b688f
TI
2179 }
2180
2181#define DEFINE_CAPMIX(num) \
2182static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2183 _DEFINE_CAPMIX(num), \
2184 _DEFINE_CAPSRC(num), \
2185 { } /* end */ \
2186}
2187
2188#define DEFINE_CAPMIX_NOSRC(num) \
2189static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2190 _DEFINE_CAPMIX(num), \
2191 { } /* end */ \
f9e336f6
TI
2192}
2193
2194/* up to three ADCs */
2195DEFINE_CAPMIX(1);
2196DEFINE_CAPMIX(2);
2197DEFINE_CAPMIX(3);
a23b688f
TI
2198DEFINE_CAPMIX_NOSRC(1);
2199DEFINE_CAPMIX_NOSRC(2);
2200DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2201
2202/*
2203 * ALC880 5-stack model
2204 *
9c7f852e
TI
2205 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2206 * Side = 0x02 (0xd)
e9edcee0
TI
2207 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2208 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2209 */
2210
2211/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2212static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2213 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2214 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2215 { } /* end */
2216};
2217
e9edcee0
TI
2218/* channel source setting (6/8 channel selection for 5-stack) */
2219/* 6ch mode */
2220static struct hda_verb alc880_fivestack_ch6_init[] = {
2221 /* set line-in to input, mute it */
2222 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2223 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2224 { } /* end */
2225};
2226
e9edcee0
TI
2227/* 8ch mode */
2228static struct hda_verb alc880_fivestack_ch8_init[] = {
2229 /* set line-in to output, unmute it */
2230 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2231 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2232 { } /* end */
2233};
2234
d2a6d7dc 2235static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2236 { 6, alc880_fivestack_ch6_init },
2237 { 8, alc880_fivestack_ch8_init },
2238};
2239
2240
2241/*
2242 * ALC880 6-stack model
2243 *
9c7f852e
TI
2244 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2245 * Side = 0x05 (0x0f)
e9edcee0
TI
2246 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2247 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2248 */
2249
2250static hda_nid_t alc880_6st_dac_nids[4] = {
2251 /* front, rear, clfe, rear_surr */
2252 0x02, 0x03, 0x04, 0x05
f12ab1e0 2253};
e9edcee0
TI
2254
2255static struct hda_input_mux alc880_6stack_capture_source = {
2256 .num_items = 4,
2257 .items = {
2258 { "Mic", 0x0 },
2259 { "Front Mic", 0x1 },
2260 { "Line", 0x2 },
2261 { "CD", 0x4 },
2262 },
2263};
2264
2265/* fixed 8-channels */
d2a6d7dc 2266static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2267 { 8, NULL },
2268};
2269
c8b6bf9b 2270static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2272 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2273 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2274 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2275 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2276 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2277 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2278 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2279 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2280 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2281 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2282 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2283 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2284 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2287 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2288 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2289 {
2290 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2291 .name = "Channel Mode",
df694daa
KY
2292 .info = alc_ch_mode_info,
2293 .get = alc_ch_mode_get,
2294 .put = alc_ch_mode_put,
16ded525
TI
2295 },
2296 { } /* end */
2297};
2298
e9edcee0
TI
2299
2300/*
2301 * ALC880 W810 model
2302 *
2303 * W810 has rear IO for:
2304 * Front (DAC 02)
2305 * Surround (DAC 03)
2306 * Center/LFE (DAC 04)
2307 * Digital out (06)
2308 *
2309 * The system also has a pair of internal speakers, and a headphone jack.
2310 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2311 *
e9edcee0
TI
2312 * There is a variable resistor to control the speaker or headphone
2313 * volume. This is a hardware-only device without a software API.
2314 *
2315 * Plugging headphones in will disable the internal speakers. This is
2316 * implemented in hardware, not via the driver using jack sense. In
2317 * a similar fashion, plugging into the rear socket marked "front" will
2318 * disable both the speakers and headphones.
2319 *
2320 * For input, there's a microphone jack, and an "audio in" jack.
2321 * These may not do anything useful with this driver yet, because I
2322 * haven't setup any initialization verbs for these yet...
2323 */
2324
2325static hda_nid_t alc880_w810_dac_nids[3] = {
2326 /* front, rear/surround, clfe */
2327 0x02, 0x03, 0x04
16ded525
TI
2328};
2329
e9edcee0 2330/* fixed 6 channels */
d2a6d7dc 2331static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2332 { 6, NULL }
2333};
2334
2335/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2336static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2337 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2338 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2339 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2340 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2341 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2342 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2343 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2344 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2346 { } /* end */
2347};
2348
2349
2350/*
2351 * Z710V model
2352 *
2353 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2354 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2355 * Line = 0x1a
e9edcee0
TI
2356 */
2357
2358static hda_nid_t alc880_z71v_dac_nids[1] = {
2359 0x02
2360};
2361#define ALC880_Z71V_HP_DAC 0x03
2362
2363/* fixed 2 channels */
d2a6d7dc 2364static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2365 { 2, NULL }
2366};
2367
c8b6bf9b 2368static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2371 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2372 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2377 { } /* end */
2378};
2379
e9edcee0 2380
e9edcee0
TI
2381/*
2382 * ALC880 F1734 model
2383 *
2384 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2385 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2386 */
2387
2388static hda_nid_t alc880_f1734_dac_nids[1] = {
2389 0x03
2390};
2391#define ALC880_F1734_HP_DAC 0x02
2392
c8b6bf9b 2393static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2394 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2395 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2396 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2397 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2398 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2399 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2400 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2401 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2402 { } /* end */
2403};
2404
937b4160
TI
2405static struct hda_input_mux alc880_f1734_capture_source = {
2406 .num_items = 2,
2407 .items = {
2408 { "Mic", 0x1 },
2409 { "CD", 0x4 },
2410 },
2411};
2412
e9edcee0 2413
e9edcee0
TI
2414/*
2415 * ALC880 ASUS model
2416 *
2417 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2418 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2419 * Mic = 0x18, Line = 0x1a
2420 */
2421
2422#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2423#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2424
c8b6bf9b 2425static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2426 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2427 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2428 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2429 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2430 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2431 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2432 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2433 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2436 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2437 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2440 {
2441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2442 .name = "Channel Mode",
df694daa
KY
2443 .info = alc_ch_mode_info,
2444 .get = alc_ch_mode_get,
2445 .put = alc_ch_mode_put,
16ded525
TI
2446 },
2447 { } /* end */
2448};
e9edcee0 2449
e9edcee0
TI
2450/*
2451 * ALC880 ASUS W1V model
2452 *
2453 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2454 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2455 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2456 */
2457
2458/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2459static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2460 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2461 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2462 { } /* end */
2463};
2464
df694daa
KY
2465/* TCL S700 */
2466static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2467 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2468 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2469 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2470 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2471 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2474 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2475 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2476 { } /* end */
2477};
2478
ccc656ce
KY
2479/* Uniwill */
2480static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2481 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2482 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2483 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2484 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2485 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2486 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2487 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2488 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2489 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2490 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2491 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2492 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2495 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2497 {
2498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2499 .name = "Channel Mode",
2500 .info = alc_ch_mode_info,
2501 .get = alc_ch_mode_get,
2502 .put = alc_ch_mode_put,
2503 },
2504 { } /* end */
2505};
2506
2cf9f0fc
TD
2507static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2508 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2509 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2510 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2511 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2512 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2513 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2514 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2515 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2516 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2517 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2518 { } /* end */
2519};
2520
ccc656ce 2521static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2523 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2525 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2528 { } /* end */
2529};
2530
2134ea4f
TI
2531/*
2532 * virtual master controls
2533 */
2534
2535/*
2536 * slave controls for virtual master
2537 */
2538static const char *alc_slave_vols[] = {
2539 "Front Playback Volume",
2540 "Surround Playback Volume",
2541 "Center Playback Volume",
2542 "LFE Playback Volume",
2543 "Side Playback Volume",
2544 "Headphone Playback Volume",
2545 "Speaker Playback Volume",
2546 "Mono Playback Volume",
2134ea4f 2547 "Line-Out Playback Volume",
26f5df26 2548 "PCM Playback Volume",
2134ea4f
TI
2549 NULL,
2550};
2551
2552static const char *alc_slave_sws[] = {
2553 "Front Playback Switch",
2554 "Surround Playback Switch",
2555 "Center Playback Switch",
2556 "LFE Playback Switch",
2557 "Side Playback Switch",
2558 "Headphone Playback Switch",
2559 "Speaker Playback Switch",
2560 "Mono Playback Switch",
edb54a55 2561 "IEC958 Playback Switch",
23033b2b
TI
2562 "Line-Out Playback Switch",
2563 "PCM Playback Switch",
2134ea4f
TI
2564 NULL,
2565};
2566
1da177e4 2567/*
e9edcee0 2568 * build control elements
1da177e4 2569 */
603c4019 2570
5b0cb1d8
JK
2571#define NID_MAPPING (-1)
2572
2573#define SUBDEV_SPEAKER_ (0 << 6)
2574#define SUBDEV_HP_ (1 << 6)
2575#define SUBDEV_LINE_ (2 << 6)
2576#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2577#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2578#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2579
603c4019
TI
2580static void alc_free_kctls(struct hda_codec *codec);
2581
67d634c0 2582#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2583/* additional beep mixers; the actual parameters are overwritten at build */
2584static struct snd_kcontrol_new alc_beep_mixer[] = {
2585 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2586 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2587 { } /* end */
2588};
67d634c0 2589#endif
45bdd1c1 2590
1da177e4
LT
2591static int alc_build_controls(struct hda_codec *codec)
2592{
2593 struct alc_spec *spec = codec->spec;
2f44f847 2594 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2595 struct snd_kcontrol_new *knew;
2596 int i, j, err;
2597 unsigned int u;
2598 hda_nid_t nid;
1da177e4
LT
2599
2600 for (i = 0; i < spec->num_mixers; i++) {
2601 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2602 if (err < 0)
2603 return err;
2604 }
f9e336f6
TI
2605 if (spec->cap_mixer) {
2606 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2607 if (err < 0)
2608 return err;
2609 }
1da177e4 2610 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2611 err = snd_hda_create_spdif_out_ctls(codec,
2612 spec->multiout.dig_out_nid);
1da177e4
LT
2613 if (err < 0)
2614 return err;
e64f14f4
TI
2615 if (!spec->no_analog) {
2616 err = snd_hda_create_spdif_share_sw(codec,
2617 &spec->multiout);
2618 if (err < 0)
2619 return err;
2620 spec->multiout.share_spdif = 1;
2621 }
1da177e4
LT
2622 }
2623 if (spec->dig_in_nid) {
2624 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2625 if (err < 0)
2626 return err;
2627 }
2134ea4f 2628
67d634c0 2629#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2630 /* create beep controls if needed */
2631 if (spec->beep_amp) {
2632 struct snd_kcontrol_new *knew;
2633 for (knew = alc_beep_mixer; knew->name; knew++) {
2634 struct snd_kcontrol *kctl;
2635 kctl = snd_ctl_new1(knew, codec);
2636 if (!kctl)
2637 return -ENOMEM;
2638 kctl->private_value = spec->beep_amp;
5e26dfd0 2639 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2640 if (err < 0)
2641 return err;
2642 }
2643 }
67d634c0 2644#endif
45bdd1c1 2645
2134ea4f 2646 /* if we have no master control, let's create it */
e64f14f4
TI
2647 if (!spec->no_analog &&
2648 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2649 unsigned int vmaster_tlv[4];
2134ea4f 2650 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2651 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2652 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2653 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2654 if (err < 0)
2655 return err;
2656 }
e64f14f4
TI
2657 if (!spec->no_analog &&
2658 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2659 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2660 NULL, alc_slave_sws);
2661 if (err < 0)
2662 return err;
2663 }
2664
5b0cb1d8 2665 /* assign Capture Source enums to NID */
fbe618f2
TI
2666 if (spec->capsrc_nids || spec->adc_nids) {
2667 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2668 if (!kctl)
2669 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2670 for (i = 0; kctl && i < kctl->count; i++) {
2671 hda_nid_t *nids = spec->capsrc_nids;
2672 if (!nids)
2673 nids = spec->adc_nids;
2674 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2675 if (err < 0)
2676 return err;
2677 }
5b0cb1d8
JK
2678 }
2679 if (spec->cap_mixer) {
2680 const char *kname = kctl ? kctl->id.name : NULL;
2681 for (knew = spec->cap_mixer; knew->name; knew++) {
2682 if (kname && strcmp(knew->name, kname) == 0)
2683 continue;
2684 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2685 for (i = 0; kctl && i < kctl->count; i++) {
2686 err = snd_hda_add_nid(codec, kctl, i,
2687 spec->adc_nids[i]);
2688 if (err < 0)
2689 return err;
2690 }
2691 }
2692 }
2693
2694 /* other nid->control mapping */
2695 for (i = 0; i < spec->num_mixers; i++) {
2696 for (knew = spec->mixers[i]; knew->name; knew++) {
2697 if (knew->iface != NID_MAPPING)
2698 continue;
2699 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2700 if (kctl == NULL)
2701 continue;
2702 u = knew->subdevice;
2703 for (j = 0; j < 4; j++, u >>= 8) {
2704 nid = u & 0x3f;
2705 if (nid == 0)
2706 continue;
2707 switch (u & 0xc0) {
2708 case SUBDEV_SPEAKER_:
2709 nid = spec->autocfg.speaker_pins[nid];
2710 break;
2711 case SUBDEV_LINE_:
2712 nid = spec->autocfg.line_out_pins[nid];
2713 break;
2714 case SUBDEV_HP_:
2715 nid = spec->autocfg.hp_pins[nid];
2716 break;
2717 default:
2718 continue;
2719 }
2720 err = snd_hda_add_nid(codec, kctl, 0, nid);
2721 if (err < 0)
2722 return err;
2723 }
2724 u = knew->private_value;
2725 for (j = 0; j < 4; j++, u >>= 8) {
2726 nid = u & 0xff;
2727 if (nid == 0)
2728 continue;
2729 err = snd_hda_add_nid(codec, kctl, 0, nid);
2730 if (err < 0)
2731 return err;
2732 }
2733 }
2734 }
bae84e70
TI
2735
2736 alc_free_kctls(codec); /* no longer needed */
2737
1da177e4
LT
2738 return 0;
2739}
2740
e9edcee0 2741
1da177e4
LT
2742/*
2743 * initialize the codec volumes, etc
2744 */
2745
e9edcee0
TI
2746/*
2747 * generic initialization of ADC, input mixers and output mixers
2748 */
2749static struct hda_verb alc880_volume_init_verbs[] = {
2750 /*
2751 * Unmute ADC0-2 and set the default input to mic-in
2752 */
71fe7b82 2753 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2755 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2756 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2757 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2759
e9edcee0
TI
2760 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2761 * mixer widget
9c7f852e
TI
2762 * Note: PASD motherboards uses the Line In 2 as the input for front
2763 * panel mic (mic 2)
1da177e4 2764 */
e9edcee0 2765 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2772 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2773
e9edcee0
TI
2774 /*
2775 * Set up output mixers (0x0c - 0x0f)
1da177e4 2776 */
e9edcee0
TI
2777 /* set vol=0 to output mixers */
2778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2780 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2781 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2782 /* set up input amps for analog loopback */
2783 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2785 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2787 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2788 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2789 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2790 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2791 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2792
2793 { }
2794};
2795
e9edcee0
TI
2796/*
2797 * 3-stack pin configuration:
2798 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2799 */
2800static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2801 /*
2802 * preset connection lists of input pins
2803 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2804 */
2805 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2806 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2807 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2808
2809 /*
2810 * Set pin mode and muting
2811 */
2812 /* set front pin widgets 0x14 for output */
05acb863 2813 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2815 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2816 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2818 /* Mic2 (as headphone out) for HP output */
2819 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2821 /* Line In pin widget for input */
05acb863 2822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 /* Line2 (as front mic) pin widget for input and vref at 80% */
2825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2827 /* CD pin widget for input */
05acb863 2828 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2829
e9edcee0
TI
2830 { }
2831};
1da177e4 2832
e9edcee0
TI
2833/*
2834 * 5-stack pin configuration:
2835 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2836 * line-in/side = 0x1a, f-mic = 0x1b
2837 */
2838static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2839 /*
2840 * preset connection lists of input pins
2841 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2842 */
e9edcee0
TI
2843 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2844 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2845
e9edcee0
TI
2846 /*
2847 * Set pin mode and muting
1da177e4 2848 */
e9edcee0
TI
2849 /* set pin widgets 0x14-0x17 for output */
2850 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2851 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2852 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2853 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2854 /* unmute pins for output (no gain on this amp) */
2855 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2857 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2858 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2859
2860 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2862 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2863 /* Mic2 (as headphone out) for HP output */
2864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2866 /* Line In pin widget for input */
2867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2869 /* Line2 (as front mic) pin widget for input and vref at 80% */
2870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2871 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2872 /* CD pin widget for input */
2873 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2874
2875 { }
2876};
2877
e9edcee0
TI
2878/*
2879 * W810 pin configuration:
2880 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2881 */
2882static struct hda_verb alc880_pin_w810_init_verbs[] = {
2883 /* hphone/speaker input selector: front DAC */
2884 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2885
05acb863 2886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2887 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2890 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2892
e9edcee0 2893 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2894 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2895
1da177e4
LT
2896 { }
2897};
2898
e9edcee0
TI
2899/*
2900 * Z71V pin configuration:
2901 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2902 */
2903static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2904 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2905 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2908
16ded525 2909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2911 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2912 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2913
2914 { }
2915};
2916
e9edcee0
TI
2917/*
2918 * 6-stack pin configuration:
9c7f852e
TI
2919 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2920 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2921 */
2922static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2923 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2924
16ded525 2925 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2929 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2930 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2931 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2932 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2933
16ded525 2934 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2935 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2936 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2937 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2938 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2939 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2941 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2942 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2943
e9edcee0
TI
2944 { }
2945};
2946
ccc656ce
KY
2947/*
2948 * Uniwill pin configuration:
2949 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2950 * line = 0x1a
2951 */
2952static struct hda_verb alc880_uniwill_init_verbs[] = {
2953 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2954
2955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2957 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2958 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2959 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2960 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2961 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2962 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2964 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2969
2970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2971 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2972 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2973 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2974 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2975 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2976 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2977 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2978 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2979
2980 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2981 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2982
2983 { }
2984};
2985
2986/*
2987* Uniwill P53
ea1fb29a 2988* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2989 */
2990static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2991 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2992
2993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2994 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2997 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2998 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3000 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3001 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3002 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3003 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3004 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3005
3006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3007 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3008 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3009 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3010 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3011 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3012
3013 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3014 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3015
3016 { }
3017};
3018
2cf9f0fc
TD
3019static struct hda_verb alc880_beep_init_verbs[] = {
3020 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3021 { }
3022};
3023
458a4fab
TI
3024/* auto-toggle front mic */
3025static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3026{
3027 unsigned int present;
3028 unsigned char bits;
ccc656ce 3029
864f92be 3030 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3031 bits = present ? HDA_AMP_MUTE : 0;
3032 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3033}
3034
4f5d1706 3035static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3036{
a9fd4f3f
TI
3037 struct alc_spec *spec = codec->spec;
3038
3039 spec->autocfg.hp_pins[0] = 0x14;
3040 spec->autocfg.speaker_pins[0] = 0x15;
3041 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3042}
3043
3044static void alc880_uniwill_init_hook(struct hda_codec *codec)
3045{
a9fd4f3f 3046 alc_automute_amp(codec);
458a4fab 3047 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3048}
3049
3050static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3051 unsigned int res)
3052{
3053 /* Looks like the unsol event is incompatible with the standard
3054 * definition. 4bit tag is placed at 28 bit!
3055 */
458a4fab 3056 switch (res >> 28) {
458a4fab
TI
3057 case ALC880_MIC_EVENT:
3058 alc880_uniwill_mic_automute(codec);
3059 break;
a9fd4f3f
TI
3060 default:
3061 alc_automute_amp_unsol_event(codec, res);
3062 break;
458a4fab 3063 }
ccc656ce
KY
3064}
3065
4f5d1706 3066static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3067{
a9fd4f3f 3068 struct alc_spec *spec = codec->spec;
ccc656ce 3069
a9fd4f3f
TI
3070 spec->autocfg.hp_pins[0] = 0x14;
3071 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3072}
3073
3074static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3075{
3076 unsigned int present;
ea1fb29a 3077
ccc656ce 3078 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3079 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3080 present &= HDA_AMP_VOLMASK;
3081 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3082 HDA_AMP_VOLMASK, present);
3083 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3084 HDA_AMP_VOLMASK, present);
ccc656ce 3085}
47fd830a 3086
ccc656ce
KY
3087static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3088 unsigned int res)
3089{
3090 /* Looks like the unsol event is incompatible with the standard
3091 * definition. 4bit tag is placed at 28 bit!
3092 */
f12ab1e0 3093 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3094 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3095 else
3096 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3097}
3098
e9edcee0
TI
3099/*
3100 * F1734 pin configuration:
3101 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3102 */
3103static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3104 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3105 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3106 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3107 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3108 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3109
e9edcee0 3110 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3111 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3112 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3113 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3114
e9edcee0
TI
3115 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3116 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3117 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3118 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3119 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3120 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3121 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3122 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3123 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3124
937b4160
TI
3125 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3126 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3127
dfc0ff62
TI
3128 { }
3129};
3130
e9edcee0
TI
3131/*
3132 * ASUS pin configuration:
3133 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3134 */
3135static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3136 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3137 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3138 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3139 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3140
3141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3142 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3143 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3146 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3147 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3148 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3149
3150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3151 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3152 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3153 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3154 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3156 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3157 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3158 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3159
e9edcee0
TI
3160 { }
3161};
16ded525 3162
e9edcee0 3163/* Enable GPIO mask and set output */
bc9f98a9
KY
3164#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3165#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3166#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3167
3168/* Clevo m520g init */
3169static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3170 /* headphone output */
3171 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3172 /* line-out */
3173 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3174 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3175 /* Line-in */
3176 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3178 /* CD */
3179 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3180 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3181 /* Mic1 (rear panel) */
3182 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3183 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3184 /* Mic2 (front panel) */
3185 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3186 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3187 /* headphone */
3188 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3189 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3190 /* change to EAPD mode */
3191 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3192 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3193
3194 { }
16ded525
TI
3195};
3196
df694daa 3197static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3198 /* change to EAPD mode */
3199 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3200 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3201
df694daa
KY
3202 /* Headphone output */
3203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3204 /* Front output*/
3205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3206 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3207
3208 /* Line In pin widget for input */
3209 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3210 /* CD pin widget for input */
3211 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3212 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3213 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3214
3215 /* change to EAPD mode */
3216 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3217 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3218
3219 { }
3220};
16ded525 3221
e9edcee0 3222/*
ae6b813a
TI
3223 * LG m1 express dual
3224 *
3225 * Pin assignment:
3226 * Rear Line-In/Out (blue): 0x14
3227 * Build-in Mic-In: 0x15
3228 * Speaker-out: 0x17
3229 * HP-Out (green): 0x1b
3230 * Mic-In/Out (red): 0x19
3231 * SPDIF-Out: 0x1e
3232 */
3233
3234/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3235static hda_nid_t alc880_lg_dac_nids[3] = {
3236 0x05, 0x02, 0x03
3237};
3238
3239/* seems analog CD is not working */
3240static struct hda_input_mux alc880_lg_capture_source = {
3241 .num_items = 3,
3242 .items = {
3243 { "Mic", 0x1 },
3244 { "Line", 0x5 },
3245 { "Internal Mic", 0x6 },
3246 },
3247};
3248
3249/* 2,4,6 channel modes */
3250static struct hda_verb alc880_lg_ch2_init[] = {
3251 /* set line-in and mic-in to input */
3252 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3253 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3254 { }
3255};
3256
3257static struct hda_verb alc880_lg_ch4_init[] = {
3258 /* set line-in to out and mic-in to input */
3259 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3260 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3261 { }
3262};
3263
3264static struct hda_verb alc880_lg_ch6_init[] = {
3265 /* set line-in and mic-in to output */
3266 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3267 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3268 { }
3269};
3270
3271static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3272 { 2, alc880_lg_ch2_init },
3273 { 4, alc880_lg_ch4_init },
3274 { 6, alc880_lg_ch6_init },
3275};
3276
3277static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3278 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3279 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3280 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3281 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3282 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3283 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3284 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3285 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3286 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3288 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3289 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3290 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3291 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3292 {
3293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3294 .name = "Channel Mode",
3295 .info = alc_ch_mode_info,
3296 .get = alc_ch_mode_get,
3297 .put = alc_ch_mode_put,
3298 },
3299 { } /* end */
3300};
3301
3302static struct hda_verb alc880_lg_init_verbs[] = {
3303 /* set capture source to mic-in */
3304 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3305 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3307 /* mute all amp mixer inputs */
3308 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3309 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3310 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3311 /* line-in to input */
3312 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3313 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3314 /* built-in mic */
3315 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3317 /* speaker-out */
3318 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3319 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3320 /* mic-in to input */
3321 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3322 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3323 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3324 /* HP-out */
3325 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3326 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3327 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3328 /* jack sense */
a9fd4f3f 3329 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3330 { }
3331};
3332
3333/* toggle speaker-output according to the hp-jack state */
4f5d1706 3334static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3335{
a9fd4f3f 3336 struct alc_spec *spec = codec->spec;
ae6b813a 3337
a9fd4f3f
TI
3338 spec->autocfg.hp_pins[0] = 0x1b;
3339 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3340}
3341
d681518a
TI
3342/*
3343 * LG LW20
3344 *
3345 * Pin assignment:
3346 * Speaker-out: 0x14
3347 * Mic-In: 0x18
e4f41da9
CM
3348 * Built-in Mic-In: 0x19
3349 * Line-In: 0x1b
3350 * HP-Out: 0x1a
d681518a
TI
3351 * SPDIF-Out: 0x1e
3352 */
3353
d681518a 3354static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3355 .num_items = 3,
d681518a
TI
3356 .items = {
3357 { "Mic", 0x0 },
3358 { "Internal Mic", 0x1 },
e4f41da9 3359 { "Line In", 0x2 },
d681518a
TI
3360 },
3361};
3362
0a8c5da3
CM
3363#define alc880_lg_lw_modes alc880_threestack_modes
3364
d681518a 3365static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3366 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3367 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3368 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3369 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3370 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3371 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3372 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3373 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3374 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3375 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3378 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3379 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3380 {
3381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3382 .name = "Channel Mode",
3383 .info = alc_ch_mode_info,
3384 .get = alc_ch_mode_get,
3385 .put = alc_ch_mode_put,
3386 },
d681518a
TI
3387 { } /* end */
3388};
3389
3390static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3391 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3392 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3393 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3394
d681518a
TI
3395 /* set capture source to mic-in */
3396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3397 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3398 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3400 /* speaker-out */
3401 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3402 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3403 /* HP-out */
d681518a
TI
3404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3406 /* mic-in to input */
3407 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3408 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3409 /* built-in mic */
3410 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3411 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3412 /* jack sense */
a9fd4f3f 3413 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3414 { }
3415};
3416
3417/* toggle speaker-output according to the hp-jack state */
4f5d1706 3418static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3419{
a9fd4f3f 3420 struct alc_spec *spec = codec->spec;
d681518a 3421
a9fd4f3f
TI
3422 spec->autocfg.hp_pins[0] = 0x1b;
3423 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3424}
3425
df99cd33
TI
3426static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3427 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3428 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3430 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3431 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3432 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3433 { } /* end */
3434};
3435
3436static struct hda_input_mux alc880_medion_rim_capture_source = {
3437 .num_items = 2,
3438 .items = {
3439 { "Mic", 0x0 },
3440 { "Internal Mic", 0x1 },
3441 },
3442};
3443
3444static struct hda_verb alc880_medion_rim_init_verbs[] = {
3445 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3446
3447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3449
3450 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3453 /* Mic2 (as headphone out) for HP output */
3454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3456 /* Internal Speaker */
3457 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3458 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3459
3460 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3461 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3462
3463 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3464 { }
3465};
3466
3467/* toggle speaker-output according to the hp-jack state */
3468static void alc880_medion_rim_automute(struct hda_codec *codec)
3469{
a9fd4f3f
TI
3470 struct alc_spec *spec = codec->spec;
3471 alc_automute_amp(codec);
3472 /* toggle EAPD */
3473 if (spec->jack_present)
df99cd33
TI
3474 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3475 else
3476 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3477}
3478
3479static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3480 unsigned int res)
3481{
3482 /* Looks like the unsol event is incompatible with the standard
3483 * definition. 4bit tag is placed at 28 bit!
3484 */
3485 if ((res >> 28) == ALC880_HP_EVENT)
3486 alc880_medion_rim_automute(codec);
3487}
3488
4f5d1706 3489static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3490{
3491 struct alc_spec *spec = codec->spec;
3492
3493 spec->autocfg.hp_pins[0] = 0x14;
3494 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3495}
3496
cb53c626
TI
3497#ifdef CONFIG_SND_HDA_POWER_SAVE
3498static struct hda_amp_list alc880_loopbacks[] = {
3499 { 0x0b, HDA_INPUT, 0 },
3500 { 0x0b, HDA_INPUT, 1 },
3501 { 0x0b, HDA_INPUT, 2 },
3502 { 0x0b, HDA_INPUT, 3 },
3503 { 0x0b, HDA_INPUT, 4 },
3504 { } /* end */
3505};
3506
3507static struct hda_amp_list alc880_lg_loopbacks[] = {
3508 { 0x0b, HDA_INPUT, 1 },
3509 { 0x0b, HDA_INPUT, 6 },
3510 { 0x0b, HDA_INPUT, 7 },
3511 { } /* end */
3512};
3513#endif
3514
ae6b813a
TI
3515/*
3516 * Common callbacks
e9edcee0
TI
3517 */
3518
1da177e4
LT
3519static int alc_init(struct hda_codec *codec)
3520{
3521 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3522 unsigned int i;
3523
2c3bf9ab 3524 alc_fix_pll(codec);
4a79ba34 3525 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3526
e9edcee0
TI
3527 for (i = 0; i < spec->num_init_verbs; i++)
3528 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3529
3530 if (spec->init_hook)
3531 spec->init_hook(codec);
3532
ad35879a
TI
3533#ifdef CONFIG_SND_HDA_POWER_SAVE
3534 if (codec->patch_ops.check_power_status)
3535 codec->patch_ops.check_power_status(codec, 0x01);
3536#endif
1da177e4
LT
3537 return 0;
3538}
3539
ae6b813a
TI
3540static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3541{
3542 struct alc_spec *spec = codec->spec;
3543
3544 if (spec->unsol_event)
3545 spec->unsol_event(codec, res);
3546}
3547
cb53c626
TI
3548#ifdef CONFIG_SND_HDA_POWER_SAVE
3549static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3550{
3551 struct alc_spec *spec = codec->spec;
3552 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3553}
3554#endif
3555
1da177e4
LT
3556/*
3557 * Analog playback callbacks
3558 */
3559static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3560 struct hda_codec *codec,
c8b6bf9b 3561 struct snd_pcm_substream *substream)
1da177e4
LT
3562{
3563 struct alc_spec *spec = codec->spec;
9a08160b
TI
3564 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3565 hinfo);
1da177e4
LT
3566}
3567
3568static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3569 struct hda_codec *codec,
3570 unsigned int stream_tag,
3571 unsigned int format,
c8b6bf9b 3572 struct snd_pcm_substream *substream)
1da177e4
LT
3573{
3574 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3575 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3576 stream_tag, format, substream);
1da177e4
LT
3577}
3578
3579static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3580 struct hda_codec *codec,
c8b6bf9b 3581 struct snd_pcm_substream *substream)
1da177e4
LT
3582{
3583 struct alc_spec *spec = codec->spec;
3584 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3585}
3586
3587/*
3588 * Digital out
3589 */
3590static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3591 struct hda_codec *codec,
c8b6bf9b 3592 struct snd_pcm_substream *substream)
1da177e4
LT
3593{
3594 struct alc_spec *spec = codec->spec;
3595 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3596}
3597
6b97eb45
TI
3598static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3599 struct hda_codec *codec,
3600 unsigned int stream_tag,
3601 unsigned int format,
3602 struct snd_pcm_substream *substream)
3603{
3604 struct alc_spec *spec = codec->spec;
3605 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3606 stream_tag, format, substream);
3607}
3608
9b5f12e5
TI
3609static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3610 struct hda_codec *codec,
3611 struct snd_pcm_substream *substream)
3612{
3613 struct alc_spec *spec = codec->spec;
3614 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3615}
3616
1da177e4
LT
3617static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3618 struct hda_codec *codec,
c8b6bf9b 3619 struct snd_pcm_substream *substream)
1da177e4
LT
3620{
3621 struct alc_spec *spec = codec->spec;
3622 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3623}
3624
3625/*
3626 * Analog capture
3627 */
6330079f 3628static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3629 struct hda_codec *codec,
3630 unsigned int stream_tag,
3631 unsigned int format,
c8b6bf9b 3632 struct snd_pcm_substream *substream)
1da177e4
LT
3633{
3634 struct alc_spec *spec = codec->spec;
3635
6330079f 3636 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3637 stream_tag, 0, format);
3638 return 0;
3639}
3640
6330079f 3641static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3642 struct hda_codec *codec,
c8b6bf9b 3643 struct snd_pcm_substream *substream)
1da177e4
LT
3644{
3645 struct alc_spec *spec = codec->spec;
3646
888afa15
TI
3647 snd_hda_codec_cleanup_stream(codec,
3648 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3649 return 0;
3650}
3651
840b64c0
TI
3652/* analog capture with dynamic dual-adc changes */
3653static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3654 struct hda_codec *codec,
3655 unsigned int stream_tag,
3656 unsigned int format,
3657 struct snd_pcm_substream *substream)
3658{
3659 struct alc_spec *spec = codec->spec;
3660 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3661 spec->cur_adc_stream_tag = stream_tag;
3662 spec->cur_adc_format = format;
3663 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3664 return 0;
3665}
3666
3667static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3668 struct hda_codec *codec,
3669 struct snd_pcm_substream *substream)
3670{
3671 struct alc_spec *spec = codec->spec;
3672 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3673 spec->cur_adc = 0;
3674 return 0;
3675}
3676
3677static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3678 .substreams = 1,
3679 .channels_min = 2,
3680 .channels_max = 2,
3681 .nid = 0, /* fill later */
3682 .ops = {
3683 .prepare = dualmic_capture_pcm_prepare,
3684 .cleanup = dualmic_capture_pcm_cleanup
3685 },
3686};
1da177e4
LT
3687
3688/*
3689 */
3690static struct hda_pcm_stream alc880_pcm_analog_playback = {
3691 .substreams = 1,
3692 .channels_min = 2,
3693 .channels_max = 8,
e9edcee0 3694 /* NID is set in alc_build_pcms */
1da177e4
LT
3695 .ops = {
3696 .open = alc880_playback_pcm_open,
3697 .prepare = alc880_playback_pcm_prepare,
3698 .cleanup = alc880_playback_pcm_cleanup
3699 },
3700};
3701
3702static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3703 .substreams = 1,
3704 .channels_min = 2,
3705 .channels_max = 2,
3706 /* NID is set in alc_build_pcms */
3707};
3708
3709static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3710 .substreams = 1,
3711 .channels_min = 2,
3712 .channels_max = 2,
3713 /* NID is set in alc_build_pcms */
3714};
3715
3716static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3717 .substreams = 2, /* can be overridden */
1da177e4
LT
3718 .channels_min = 2,
3719 .channels_max = 2,
e9edcee0 3720 /* NID is set in alc_build_pcms */
1da177e4 3721 .ops = {
6330079f
TI
3722 .prepare = alc880_alt_capture_pcm_prepare,
3723 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3724 },
3725};
3726
3727static struct hda_pcm_stream alc880_pcm_digital_playback = {
3728 .substreams = 1,
3729 .channels_min = 2,
3730 .channels_max = 2,
3731 /* NID is set in alc_build_pcms */
3732 .ops = {
3733 .open = alc880_dig_playback_pcm_open,
6b97eb45 3734 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3735 .prepare = alc880_dig_playback_pcm_prepare,
3736 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3737 },
3738};
3739
3740static struct hda_pcm_stream alc880_pcm_digital_capture = {
3741 .substreams = 1,
3742 .channels_min = 2,
3743 .channels_max = 2,
3744 /* NID is set in alc_build_pcms */
3745};
3746
4c5186ed 3747/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3748static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3749 .substreams = 0,
3750 .channels_min = 0,
3751 .channels_max = 0,
3752};
3753
1da177e4
LT
3754static int alc_build_pcms(struct hda_codec *codec)
3755{
3756 struct alc_spec *spec = codec->spec;
3757 struct hda_pcm *info = spec->pcm_rec;
3758 int i;
3759
3760 codec->num_pcms = 1;
3761 codec->pcm_info = info;
3762
e64f14f4
TI
3763 if (spec->no_analog)
3764 goto skip_analog;
3765
812a2cca
TI
3766 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3767 "%s Analog", codec->chip_name);
1da177e4 3768 info->name = spec->stream_name_analog;
274693f3 3769
4a471b7d 3770 if (spec->stream_analog_playback) {
da3cec35
TI
3771 if (snd_BUG_ON(!spec->multiout.dac_nids))
3772 return -EINVAL;
4a471b7d
TI
3773 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3774 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3775 }
3776 if (spec->stream_analog_capture) {
da3cec35
TI
3777 if (snd_BUG_ON(!spec->adc_nids))
3778 return -EINVAL;
4a471b7d
TI
3779 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3780 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3781 }
3782
3783 if (spec->channel_mode) {
3784 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3785 for (i = 0; i < spec->num_channel_mode; i++) {
3786 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3787 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3788 }
1da177e4
LT
3789 }
3790 }
3791
e64f14f4 3792 skip_analog:
e08a007d 3793 /* SPDIF for stream index #1 */
1da177e4 3794 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3795 snprintf(spec->stream_name_digital,
3796 sizeof(spec->stream_name_digital),
3797 "%s Digital", codec->chip_name);
e08a007d 3798 codec->num_pcms = 2;
b25c9da1 3799 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3800 info = spec->pcm_rec + 1;
1da177e4 3801 info->name = spec->stream_name_digital;
8c441982
TI
3802 if (spec->dig_out_type)
3803 info->pcm_type = spec->dig_out_type;
3804 else
3805 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3806 if (spec->multiout.dig_out_nid &&
3807 spec->stream_digital_playback) {
1da177e4
LT
3808 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3809 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3810 }
4a471b7d
TI
3811 if (spec->dig_in_nid &&
3812 spec->stream_digital_capture) {
1da177e4
LT
3813 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3814 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3815 }
963f803f
TI
3816 /* FIXME: do we need this for all Realtek codec models? */
3817 codec->spdif_status_reset = 1;
1da177e4
LT
3818 }
3819
e64f14f4
TI
3820 if (spec->no_analog)
3821 return 0;
3822
e08a007d
TI
3823 /* If the use of more than one ADC is requested for the current
3824 * model, configure a second analog capture-only PCM.
3825 */
3826 /* Additional Analaog capture for index #2 */
6330079f
TI
3827 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3828 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3829 codec->num_pcms = 3;
c06134d7 3830 info = spec->pcm_rec + 2;
e08a007d 3831 info->name = spec->stream_name_analog;
6330079f
TI
3832 if (spec->alt_dac_nid) {
3833 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3834 *spec->stream_analog_alt_playback;
3835 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3836 spec->alt_dac_nid;
3837 } else {
3838 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3839 alc_pcm_null_stream;
3840 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3841 }
3842 if (spec->num_adc_nids > 1) {
3843 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3844 *spec->stream_analog_alt_capture;
3845 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3846 spec->adc_nids[1];
3847 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3848 spec->num_adc_nids - 1;
3849 } else {
3850 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3851 alc_pcm_null_stream;
3852 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3853 }
3854 }
3855
1da177e4
LT
3856 return 0;
3857}
3858
a4e09aa3
TI
3859static inline void alc_shutup(struct hda_codec *codec)
3860{
3861 snd_hda_shutup_pins(codec);
3862}
3863
603c4019
TI
3864static void alc_free_kctls(struct hda_codec *codec)
3865{
3866 struct alc_spec *spec = codec->spec;
3867
3868 if (spec->kctls.list) {
3869 struct snd_kcontrol_new *kctl = spec->kctls.list;
3870 int i;
3871 for (i = 0; i < spec->kctls.used; i++)
3872 kfree(kctl[i].name);
3873 }
3874 snd_array_free(&spec->kctls);
3875}
3876
1da177e4
LT
3877static void alc_free(struct hda_codec *codec)
3878{
e9edcee0 3879 struct alc_spec *spec = codec->spec;
e9edcee0 3880
f12ab1e0 3881 if (!spec)
e9edcee0
TI
3882 return;
3883
a4e09aa3 3884 alc_shutup(codec);
603c4019 3885 alc_free_kctls(codec);
e9edcee0 3886 kfree(spec);
680cd536 3887 snd_hda_detach_beep_device(codec);
1da177e4
LT
3888}
3889
f5de24b0 3890#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3891static void alc_power_eapd(struct hda_codec *codec)
3892{
3893 /* We currently only handle front, HP */
3894 switch (codec->vendor_id) {
3895 case 0x10ec0260:
9e4c8496
TI
3896 set_eapd(codec, 0x0f, 0);
3897 set_eapd(codec, 0x10, 0);
c97259df
DC
3898 break;
3899 case 0x10ec0262:
3900 case 0x10ec0267:
3901 case 0x10ec0268:
3902 case 0x10ec0269:
9e4c8496 3903 case 0x10ec0270:
c97259df
DC
3904 case 0x10ec0272:
3905 case 0x10ec0660:
3906 case 0x10ec0662:
3907 case 0x10ec0663:
3908 case 0x10ec0862:
3909 case 0x10ec0889:
9e4c8496
TI
3910 set_eapd(codec, 0x14, 0);
3911 set_eapd(codec, 0x15, 0);
c97259df
DC
3912 break;
3913 }
3914}
3915
f5de24b0
HM
3916static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3917{
3918 struct alc_spec *spec = codec->spec;
a4e09aa3 3919 alc_shutup(codec);
f5de24b0 3920 if (spec && spec->power_hook)
c97259df 3921 spec->power_hook(codec);
f5de24b0
HM
3922 return 0;
3923}
3924#endif
3925
e044c39a 3926#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3927static int alc_resume(struct hda_codec *codec)
3928{
e044c39a
TI
3929 codec->patch_ops.init(codec);
3930 snd_hda_codec_resume_amp(codec);
3931 snd_hda_codec_resume_cache(codec);
ad35879a
TI
3932#ifdef CONFIG_SND_HDA_POWER_SAVE
3933 if (codec->patch_ops.check_power_status)
3934 codec->patch_ops.check_power_status(codec, 0x01);
3935#endif
e044c39a
TI
3936 return 0;
3937}
e044c39a
TI
3938#endif
3939
1da177e4
LT
3940/*
3941 */
3942static struct hda_codec_ops alc_patch_ops = {
3943 .build_controls = alc_build_controls,
3944 .build_pcms = alc_build_pcms,
3945 .init = alc_init,
3946 .free = alc_free,
ae6b813a 3947 .unsol_event = alc_unsol_event,
e044c39a
TI
3948#ifdef SND_HDA_NEEDS_RESUME
3949 .resume = alc_resume,
3950#endif
cb53c626 3951#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 3952 .suspend = alc_suspend,
cb53c626
TI
3953 .check_power_status = alc_check_power_status,
3954#endif
c97259df 3955 .reboot_notify = alc_shutup,
1da177e4
LT
3956};
3957
c027ddcd
KY
3958/* replace the codec chip_name with the given string */
3959static int alc_codec_rename(struct hda_codec *codec, const char *name)
3960{
3961 kfree(codec->chip_name);
3962 codec->chip_name = kstrdup(name, GFP_KERNEL);
3963 if (!codec->chip_name) {
3964 alc_free(codec);
3965 return -ENOMEM;
3966 }
3967 return 0;
3968}
3969
2fa522be
TI
3970/*
3971 * Test configuration for debugging
3972 *
3973 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3974 * enum controls.
3975 */
3976#ifdef CONFIG_SND_DEBUG
3977static hda_nid_t alc880_test_dac_nids[4] = {
3978 0x02, 0x03, 0x04, 0x05
3979};
3980
3981static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3982 .num_items = 7,
2fa522be
TI
3983 .items = {
3984 { "In-1", 0x0 },
3985 { "In-2", 0x1 },
3986 { "In-3", 0x2 },
3987 { "In-4", 0x3 },
3988 { "CD", 0x4 },
ae6b813a
TI
3989 { "Front", 0x5 },
3990 { "Surround", 0x6 },
2fa522be
TI
3991 },
3992};
3993
d2a6d7dc 3994static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3995 { 2, NULL },
fd2c326d 3996 { 4, NULL },
2fa522be 3997 { 6, NULL },
fd2c326d 3998 { 8, NULL },
2fa522be
TI
3999};
4000
9c7f852e
TI
4001static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4002 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4003{
4004 static char *texts[] = {
4005 "N/A", "Line Out", "HP Out",
4006 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4007 };
4008 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4009 uinfo->count = 1;
4010 uinfo->value.enumerated.items = 8;
4011 if (uinfo->value.enumerated.item >= 8)
4012 uinfo->value.enumerated.item = 7;
4013 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4014 return 0;
4015}
4016
9c7f852e
TI
4017static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4018 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4019{
4020 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4021 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4022 unsigned int pin_ctl, item = 0;
4023
4024 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4025 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4026 if (pin_ctl & AC_PINCTL_OUT_EN) {
4027 if (pin_ctl & AC_PINCTL_HP_EN)
4028 item = 2;
4029 else
4030 item = 1;
4031 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4032 switch (pin_ctl & AC_PINCTL_VREFEN) {
4033 case AC_PINCTL_VREF_HIZ: item = 3; break;
4034 case AC_PINCTL_VREF_50: item = 4; break;
4035 case AC_PINCTL_VREF_GRD: item = 5; break;
4036 case AC_PINCTL_VREF_80: item = 6; break;
4037 case AC_PINCTL_VREF_100: item = 7; break;
4038 }
4039 }
4040 ucontrol->value.enumerated.item[0] = item;
4041 return 0;
4042}
4043
9c7f852e
TI
4044static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4045 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4046{
4047 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4048 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4049 static unsigned int ctls[] = {
4050 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4051 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4052 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4053 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4054 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4055 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4056 };
4057 unsigned int old_ctl, new_ctl;
4058
4059 old_ctl = snd_hda_codec_read(codec, nid, 0,
4060 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4061 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4062 if (old_ctl != new_ctl) {
82beb8fd
TI
4063 int val;
4064 snd_hda_codec_write_cache(codec, nid, 0,
4065 AC_VERB_SET_PIN_WIDGET_CONTROL,
4066 new_ctl);
47fd830a
TI
4067 val = ucontrol->value.enumerated.item[0] >= 3 ?
4068 HDA_AMP_MUTE : 0;
4069 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4070 HDA_AMP_MUTE, val);
2fa522be
TI
4071 return 1;
4072 }
4073 return 0;
4074}
4075
9c7f852e
TI
4076static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4077 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4078{
4079 static char *texts[] = {
4080 "Front", "Surround", "CLFE", "Side"
4081 };
4082 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4083 uinfo->count = 1;
4084 uinfo->value.enumerated.items = 4;
4085 if (uinfo->value.enumerated.item >= 4)
4086 uinfo->value.enumerated.item = 3;
4087 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4088 return 0;
4089}
4090
9c7f852e
TI
4091static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4092 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4093{
4094 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4095 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4096 unsigned int sel;
4097
4098 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4099 ucontrol->value.enumerated.item[0] = sel & 3;
4100 return 0;
4101}
4102
9c7f852e
TI
4103static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4104 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4105{
4106 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4107 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4108 unsigned int sel;
4109
4110 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4111 if (ucontrol->value.enumerated.item[0] != sel) {
4112 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4113 snd_hda_codec_write_cache(codec, nid, 0,
4114 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4115 return 1;
4116 }
4117 return 0;
4118}
4119
4120#define PIN_CTL_TEST(xname,nid) { \
4121 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4122 .name = xname, \
5b0cb1d8 4123 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4124 .info = alc_test_pin_ctl_info, \
4125 .get = alc_test_pin_ctl_get, \
4126 .put = alc_test_pin_ctl_put, \
4127 .private_value = nid \
4128 }
4129
4130#define PIN_SRC_TEST(xname,nid) { \
4131 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4132 .name = xname, \
5b0cb1d8 4133 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4134 .info = alc_test_pin_src_info, \
4135 .get = alc_test_pin_src_get, \
4136 .put = alc_test_pin_src_put, \
4137 .private_value = nid \
4138 }
4139
c8b6bf9b 4140static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4141 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4142 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4143 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4144 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4145 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4146 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4147 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4148 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4149 PIN_CTL_TEST("Front Pin Mode", 0x14),
4150 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4151 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4152 PIN_CTL_TEST("Side Pin Mode", 0x17),
4153 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4154 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4155 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4156 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4157 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4158 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4159 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4160 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4161 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4162 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4163 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4164 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4165 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4166 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4167 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4168 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4169 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4170 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4171 {
4172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4173 .name = "Channel Mode",
df694daa
KY
4174 .info = alc_ch_mode_info,
4175 .get = alc_ch_mode_get,
4176 .put = alc_ch_mode_put,
2fa522be
TI
4177 },
4178 { } /* end */
4179};
4180
4181static struct hda_verb alc880_test_init_verbs[] = {
4182 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4186 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4187 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4188 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4189 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4190 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4191 /* Vol output for 0x0c-0x0f */
05acb863
TI
4192 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4193 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4196 /* Set output pins 0x14-0x17 */
05acb863
TI
4197 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4201 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4202 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4204 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4205 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4206 /* Set input pins 0x18-0x1c */
16ded525
TI
4207 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4208 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4209 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4210 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4211 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4212 /* Mute input pins 0x18-0x1b */
05acb863
TI
4213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4215 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4216 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4217 /* ADC set up */
05acb863 4218 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4219 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4221 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4222 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4223 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4224 /* Analog input/passthru */
4225 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4226 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4227 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4228 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4229 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4230 { }
4231};
4232#endif
4233
1da177e4
LT
4234/*
4235 */
4236
f5fcc13c
TI
4237static const char *alc880_models[ALC880_MODEL_LAST] = {
4238 [ALC880_3ST] = "3stack",
4239 [ALC880_TCL_S700] = "tcl",
4240 [ALC880_3ST_DIG] = "3stack-digout",
4241 [ALC880_CLEVO] = "clevo",
4242 [ALC880_5ST] = "5stack",
4243 [ALC880_5ST_DIG] = "5stack-digout",
4244 [ALC880_W810] = "w810",
4245 [ALC880_Z71V] = "z71v",
4246 [ALC880_6ST] = "6stack",
4247 [ALC880_6ST_DIG] = "6stack-digout",
4248 [ALC880_ASUS] = "asus",
4249 [ALC880_ASUS_W1V] = "asus-w1v",
4250 [ALC880_ASUS_DIG] = "asus-dig",
4251 [ALC880_ASUS_DIG2] = "asus-dig2",
4252 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4253 [ALC880_UNIWILL_P53] = "uniwill-p53",
4254 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4255 [ALC880_F1734] = "F1734",
4256 [ALC880_LG] = "lg",
4257 [ALC880_LG_LW] = "lg-lw",
df99cd33 4258 [ALC880_MEDION_RIM] = "medion",
2fa522be 4259#ifdef CONFIG_SND_DEBUG
f5fcc13c 4260 [ALC880_TEST] = "test",
2fa522be 4261#endif
f5fcc13c
TI
4262 [ALC880_AUTO] = "auto",
4263};
4264
4265static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4266 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4267 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4268 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4269 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4270 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4271 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4272 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4273 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4274 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4275 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4276 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4277 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4278 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4279 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4280 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4281 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4282 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4283 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4284 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4285 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4286 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4287 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4288 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4289 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4290 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4291 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4292 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4293 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4294 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4295 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4296 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4297 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4298 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4299 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4300 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4301 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4302 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4303 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4304 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4305 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4306 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4307 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4308 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4309 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4310 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4311 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4312 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4313 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4314 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4315 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4316 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4317 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4318 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4319 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4320 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4321 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4322 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4323 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4324 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4325 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4326 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4327 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4328 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4329 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4330 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4331 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4332 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4333 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4334 /* default Intel */
4335 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4336 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4337 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4338 {}
4339};
4340
16ded525 4341/*
df694daa 4342 * ALC880 codec presets
16ded525 4343 */
16ded525
TI
4344static struct alc_config_preset alc880_presets[] = {
4345 [ALC880_3ST] = {
e9edcee0 4346 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4347 .init_verbs = { alc880_volume_init_verbs,
4348 alc880_pin_3stack_init_verbs },
16ded525 4349 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4350 .dac_nids = alc880_dac_nids,
16ded525
TI
4351 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4352 .channel_mode = alc880_threestack_modes,
4e195a7b 4353 .need_dac_fix = 1,
16ded525
TI
4354 .input_mux = &alc880_capture_source,
4355 },
4356 [ALC880_3ST_DIG] = {
e9edcee0 4357 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4358 .init_verbs = { alc880_volume_init_verbs,
4359 alc880_pin_3stack_init_verbs },
16ded525 4360 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4361 .dac_nids = alc880_dac_nids,
4362 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4363 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4364 .channel_mode = alc880_threestack_modes,
4e195a7b 4365 .need_dac_fix = 1,
16ded525
TI
4366 .input_mux = &alc880_capture_source,
4367 },
df694daa
KY
4368 [ALC880_TCL_S700] = {
4369 .mixers = { alc880_tcl_s700_mixer },
4370 .init_verbs = { alc880_volume_init_verbs,
4371 alc880_pin_tcl_S700_init_verbs,
4372 alc880_gpio2_init_verbs },
4373 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4374 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4375 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4376 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4377 .hp_nid = 0x03,
4378 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4379 .channel_mode = alc880_2_jack_modes,
4380 .input_mux = &alc880_capture_source,
4381 },
16ded525 4382 [ALC880_5ST] = {
f12ab1e0
TI
4383 .mixers = { alc880_three_stack_mixer,
4384 alc880_five_stack_mixer},
4385 .init_verbs = { alc880_volume_init_verbs,
4386 alc880_pin_5stack_init_verbs },
16ded525
TI
4387 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4388 .dac_nids = alc880_dac_nids,
16ded525
TI
4389 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4390 .channel_mode = alc880_fivestack_modes,
4391 .input_mux = &alc880_capture_source,
4392 },
4393 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4394 .mixers = { alc880_three_stack_mixer,
4395 alc880_five_stack_mixer },
4396 .init_verbs = { alc880_volume_init_verbs,
4397 alc880_pin_5stack_init_verbs },
16ded525
TI
4398 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4399 .dac_nids = alc880_dac_nids,
4400 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4401 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4402 .channel_mode = alc880_fivestack_modes,
4403 .input_mux = &alc880_capture_source,
4404 },
b6482d48
TI
4405 [ALC880_6ST] = {
4406 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4407 .init_verbs = { alc880_volume_init_verbs,
4408 alc880_pin_6stack_init_verbs },
b6482d48
TI
4409 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4410 .dac_nids = alc880_6st_dac_nids,
4411 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4412 .channel_mode = alc880_sixstack_modes,
4413 .input_mux = &alc880_6stack_capture_source,
4414 },
16ded525 4415 [ALC880_6ST_DIG] = {
e9edcee0 4416 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4417 .init_verbs = { alc880_volume_init_verbs,
4418 alc880_pin_6stack_init_verbs },
16ded525
TI
4419 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4420 .dac_nids = alc880_6st_dac_nids,
4421 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4422 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4423 .channel_mode = alc880_sixstack_modes,
4424 .input_mux = &alc880_6stack_capture_source,
4425 },
4426 [ALC880_W810] = {
e9edcee0 4427 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4428 .init_verbs = { alc880_volume_init_verbs,
4429 alc880_pin_w810_init_verbs,
b0af0de5 4430 alc880_gpio2_init_verbs },
16ded525
TI
4431 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4432 .dac_nids = alc880_w810_dac_nids,
4433 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4434 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4435 .channel_mode = alc880_w810_modes,
4436 .input_mux = &alc880_capture_source,
4437 },
4438 [ALC880_Z71V] = {
e9edcee0 4439 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4440 .init_verbs = { alc880_volume_init_verbs,
4441 alc880_pin_z71v_init_verbs },
16ded525
TI
4442 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4443 .dac_nids = alc880_z71v_dac_nids,
4444 .dig_out_nid = ALC880_DIGOUT_NID,
4445 .hp_nid = 0x03,
e9edcee0
TI
4446 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4447 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4448 .input_mux = &alc880_capture_source,
4449 },
4450 [ALC880_F1734] = {
e9edcee0 4451 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4452 .init_verbs = { alc880_volume_init_verbs,
4453 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4454 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4455 .dac_nids = alc880_f1734_dac_nids,
4456 .hp_nid = 0x02,
4457 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4458 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4459 .input_mux = &alc880_f1734_capture_source,
4460 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4461 .setup = alc880_uniwill_p53_setup,
4462 .init_hook = alc_automute_amp,
16ded525
TI
4463 },
4464 [ALC880_ASUS] = {
e9edcee0 4465 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4466 .init_verbs = { alc880_volume_init_verbs,
4467 alc880_pin_asus_init_verbs,
e9edcee0
TI
4468 alc880_gpio1_init_verbs },
4469 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4470 .dac_nids = alc880_asus_dac_nids,
4471 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4472 .channel_mode = alc880_asus_modes,
4e195a7b 4473 .need_dac_fix = 1,
16ded525
TI
4474 .input_mux = &alc880_capture_source,
4475 },
4476 [ALC880_ASUS_DIG] = {
e9edcee0 4477 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4478 .init_verbs = { alc880_volume_init_verbs,
4479 alc880_pin_asus_init_verbs,
e9edcee0
TI
4480 alc880_gpio1_init_verbs },
4481 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4482 .dac_nids = alc880_asus_dac_nids,
16ded525 4483 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4484 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4485 .channel_mode = alc880_asus_modes,
4e195a7b 4486 .need_dac_fix = 1,
16ded525
TI
4487 .input_mux = &alc880_capture_source,
4488 },
df694daa
KY
4489 [ALC880_ASUS_DIG2] = {
4490 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4491 .init_verbs = { alc880_volume_init_verbs,
4492 alc880_pin_asus_init_verbs,
df694daa
KY
4493 alc880_gpio2_init_verbs }, /* use GPIO2 */
4494 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4495 .dac_nids = alc880_asus_dac_nids,
4496 .dig_out_nid = ALC880_DIGOUT_NID,
4497 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4498 .channel_mode = alc880_asus_modes,
4e195a7b 4499 .need_dac_fix = 1,
df694daa
KY
4500 .input_mux = &alc880_capture_source,
4501 },
16ded525 4502 [ALC880_ASUS_W1V] = {
e9edcee0 4503 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4504 .init_verbs = { alc880_volume_init_verbs,
4505 alc880_pin_asus_init_verbs,
e9edcee0
TI
4506 alc880_gpio1_init_verbs },
4507 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4508 .dac_nids = alc880_asus_dac_nids,
16ded525 4509 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4510 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4511 .channel_mode = alc880_asus_modes,
4e195a7b 4512 .need_dac_fix = 1,
16ded525
TI
4513 .input_mux = &alc880_capture_source,
4514 },
4515 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4516 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4517 .init_verbs = { alc880_volume_init_verbs,
4518 alc880_pin_asus_init_verbs },
e9edcee0
TI
4519 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4520 .dac_nids = alc880_asus_dac_nids,
16ded525 4521 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4522 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4523 .channel_mode = alc880_asus_modes,
4e195a7b 4524 .need_dac_fix = 1,
16ded525
TI
4525 .input_mux = &alc880_capture_source,
4526 },
ccc656ce
KY
4527 [ALC880_UNIWILL] = {
4528 .mixers = { alc880_uniwill_mixer },
4529 .init_verbs = { alc880_volume_init_verbs,
4530 alc880_uniwill_init_verbs },
4531 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4532 .dac_nids = alc880_asus_dac_nids,
4533 .dig_out_nid = ALC880_DIGOUT_NID,
4534 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4535 .channel_mode = alc880_threestack_modes,
4536 .need_dac_fix = 1,
4537 .input_mux = &alc880_capture_source,
4538 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4539 .setup = alc880_uniwill_setup,
a9fd4f3f 4540 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4541 },
4542 [ALC880_UNIWILL_P53] = {
4543 .mixers = { alc880_uniwill_p53_mixer },
4544 .init_verbs = { alc880_volume_init_verbs,
4545 alc880_uniwill_p53_init_verbs },
4546 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4547 .dac_nids = alc880_asus_dac_nids,
4548 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4549 .channel_mode = alc880_threestack_modes,
4550 .input_mux = &alc880_capture_source,
4551 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4552 .setup = alc880_uniwill_p53_setup,
4553 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4554 },
4555 [ALC880_FUJITSU] = {
45bdd1c1 4556 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4557 .init_verbs = { alc880_volume_init_verbs,
4558 alc880_uniwill_p53_init_verbs,
4559 alc880_beep_init_verbs },
4560 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4561 .dac_nids = alc880_dac_nids,
d53d7d9e 4562 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4563 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4564 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4565 .input_mux = &alc880_capture_source,
4566 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4567 .setup = alc880_uniwill_p53_setup,
4568 .init_hook = alc_automute_amp,
ccc656ce 4569 },
df694daa
KY
4570 [ALC880_CLEVO] = {
4571 .mixers = { alc880_three_stack_mixer },
4572 .init_verbs = { alc880_volume_init_verbs,
4573 alc880_pin_clevo_init_verbs },
4574 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4575 .dac_nids = alc880_dac_nids,
4576 .hp_nid = 0x03,
4577 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4578 .channel_mode = alc880_threestack_modes,
4e195a7b 4579 .need_dac_fix = 1,
df694daa
KY
4580 .input_mux = &alc880_capture_source,
4581 },
ae6b813a
TI
4582 [ALC880_LG] = {
4583 .mixers = { alc880_lg_mixer },
4584 .init_verbs = { alc880_volume_init_verbs,
4585 alc880_lg_init_verbs },
4586 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4587 .dac_nids = alc880_lg_dac_nids,
4588 .dig_out_nid = ALC880_DIGOUT_NID,
4589 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4590 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4591 .need_dac_fix = 1,
ae6b813a 4592 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4593 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4594 .setup = alc880_lg_setup,
4595 .init_hook = alc_automute_amp,
cb53c626
TI
4596#ifdef CONFIG_SND_HDA_POWER_SAVE
4597 .loopbacks = alc880_lg_loopbacks,
4598#endif
ae6b813a 4599 },
d681518a
TI
4600 [ALC880_LG_LW] = {
4601 .mixers = { alc880_lg_lw_mixer },
4602 .init_verbs = { alc880_volume_init_verbs,
4603 alc880_lg_lw_init_verbs },
0a8c5da3 4604 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4605 .dac_nids = alc880_dac_nids,
4606 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4607 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4608 .channel_mode = alc880_lg_lw_modes,
d681518a 4609 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4610 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4611 .setup = alc880_lg_lw_setup,
4612 .init_hook = alc_automute_amp,
d681518a 4613 },
df99cd33
TI
4614 [ALC880_MEDION_RIM] = {
4615 .mixers = { alc880_medion_rim_mixer },
4616 .init_verbs = { alc880_volume_init_verbs,
4617 alc880_medion_rim_init_verbs,
4618 alc_gpio2_init_verbs },
4619 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4620 .dac_nids = alc880_dac_nids,
4621 .dig_out_nid = ALC880_DIGOUT_NID,
4622 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4623 .channel_mode = alc880_2_jack_modes,
4624 .input_mux = &alc880_medion_rim_capture_source,
4625 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4626 .setup = alc880_medion_rim_setup,
4627 .init_hook = alc880_medion_rim_automute,
df99cd33 4628 },
16ded525
TI
4629#ifdef CONFIG_SND_DEBUG
4630 [ALC880_TEST] = {
e9edcee0
TI
4631 .mixers = { alc880_test_mixer },
4632 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4633 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4634 .dac_nids = alc880_test_dac_nids,
4635 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4636 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4637 .channel_mode = alc880_test_modes,
4638 .input_mux = &alc880_test_capture_source,
4639 },
4640#endif
4641};
4642
e9edcee0
TI
4643/*
4644 * Automatic parse of I/O pins from the BIOS configuration
4645 */
4646
e9edcee0
TI
4647enum {
4648 ALC_CTL_WIDGET_VOL,
4649 ALC_CTL_WIDGET_MUTE,
4650 ALC_CTL_BIND_MUTE,
4651};
c8b6bf9b 4652static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4653 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4654 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4655 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4656};
4657
4658/* add dynamic controls */
f12ab1e0
TI
4659static int add_control(struct alc_spec *spec, int type, const char *name,
4660 unsigned long val)
e9edcee0 4661{
c8b6bf9b 4662 struct snd_kcontrol_new *knew;
e9edcee0 4663
603c4019
TI
4664 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4665 knew = snd_array_new(&spec->kctls);
4666 if (!knew)
4667 return -ENOMEM;
e9edcee0 4668 *knew = alc880_control_templates[type];
543537bd 4669 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4670 if (!knew->name)
e9edcee0 4671 return -ENOMEM;
4d02d1b6 4672 if (get_amp_nid_(val))
5e26dfd0 4673 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4674 knew->private_value = val;
e9edcee0
TI
4675 return 0;
4676}
4677
0afe5f89
TI
4678static int add_control_with_pfx(struct alc_spec *spec, int type,
4679 const char *pfx, const char *dir,
4680 const char *sfx, unsigned long val)
4681{
4682 char name[32];
4683 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4684 return add_control(spec, type, name, val);
4685}
4686
4687#define add_pb_vol_ctrl(spec, type, pfx, val) \
4688 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4689#define add_pb_sw_ctrl(spec, type, pfx, val) \
4690 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4691
e9edcee0
TI
4692#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4693#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4694#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4695#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4696#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4697#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4698#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4699#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4700#define ALC880_PIN_CD_NID 0x1c
4701
4702/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4703static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4704 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4705{
4706 hda_nid_t nid;
4707 int assigned[4];
4708 int i, j;
4709
4710 memset(assigned, 0, sizeof(assigned));
b0af0de5 4711 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4712
4713 /* check the pins hardwired to audio widget */
4714 for (i = 0; i < cfg->line_outs; i++) {
4715 nid = cfg->line_out_pins[i];
4716 if (alc880_is_fixed_pin(nid)) {
4717 int idx = alc880_fixed_pin_idx(nid);
5014f193 4718 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4719 assigned[idx] = 1;
4720 }
4721 }
4722 /* left pins can be connect to any audio widget */
4723 for (i = 0; i < cfg->line_outs; i++) {
4724 nid = cfg->line_out_pins[i];
4725 if (alc880_is_fixed_pin(nid))
4726 continue;
4727 /* search for an empty channel */
4728 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4729 if (!assigned[j]) {
4730 spec->multiout.dac_nids[i] =
4731 alc880_idx_to_dac(j);
e9edcee0
TI
4732 assigned[j] = 1;
4733 break;
4734 }
4735 }
4736 }
4737 spec->multiout.num_dacs = cfg->line_outs;
4738 return 0;
4739}
4740
4741/* add playback controls from the parsed DAC table */
df694daa
KY
4742static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4743 const struct auto_pin_cfg *cfg)
e9edcee0 4744{
f12ab1e0
TI
4745 static const char *chname[4] = {
4746 "Front", "Surround", NULL /*CLFE*/, "Side"
4747 };
e9edcee0
TI
4748 hda_nid_t nid;
4749 int i, err;
4750
4751 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4752 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4753 continue;
4754 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4755 if (i == 2) {
4756 /* Center/LFE */
0afe5f89
TI
4757 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4758 "Center",
f12ab1e0
TI
4759 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4760 HDA_OUTPUT));
4761 if (err < 0)
e9edcee0 4762 return err;
0afe5f89
TI
4763 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4764 "LFE",
f12ab1e0
TI
4765 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4766 HDA_OUTPUT));
4767 if (err < 0)
e9edcee0 4768 return err;
0afe5f89
TI
4769 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4770 "Center",
f12ab1e0
TI
4771 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4772 HDA_INPUT));
4773 if (err < 0)
e9edcee0 4774 return err;
0afe5f89
TI
4775 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4776 "LFE",
f12ab1e0
TI
4777 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4778 HDA_INPUT));
4779 if (err < 0)
e9edcee0
TI
4780 return err;
4781 } else {
cb162b6b
TI
4782 const char *pfx;
4783 if (cfg->line_outs == 1 &&
4784 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4785 pfx = "Speaker";
4786 else
4787 pfx = chname[i];
0afe5f89 4788 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4789 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4790 HDA_OUTPUT));
4791 if (err < 0)
e9edcee0 4792 return err;
0afe5f89 4793 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4794 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4795 HDA_INPUT));
4796 if (err < 0)
e9edcee0
TI
4797 return err;
4798 }
4799 }
e9edcee0
TI
4800 return 0;
4801}
4802
8d88bc3d
TI
4803/* add playback controls for speaker and HP outputs */
4804static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4805 const char *pfx)
e9edcee0
TI
4806{
4807 hda_nid_t nid;
4808 int err;
4809
f12ab1e0 4810 if (!pin)
e9edcee0
TI
4811 return 0;
4812
4813 if (alc880_is_fixed_pin(pin)) {
4814 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4815 /* specify the DAC as the extra output */
f12ab1e0 4816 if (!spec->multiout.hp_nid)
e9edcee0 4817 spec->multiout.hp_nid = nid;
82bc955f
TI
4818 else
4819 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4820 /* control HP volume/switch on the output mixer amp */
4821 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4822 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4823 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4824 if (err < 0)
e9edcee0 4825 return err;
0afe5f89 4826 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4827 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4828 if (err < 0)
e9edcee0
TI
4829 return err;
4830 } else if (alc880_is_multi_pin(pin)) {
4831 /* set manual connection */
e9edcee0 4832 /* we have only a switch on HP-out PIN */
0afe5f89 4833 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4834 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4835 if (err < 0)
e9edcee0
TI
4836 return err;
4837 }
4838 return 0;
4839}
4840
4841/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4842static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4843 const char *ctlname,
df694daa 4844 int idx, hda_nid_t mix_nid)
e9edcee0 4845{
df694daa 4846 int err;
e9edcee0 4847
0afe5f89 4848 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4849 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4850 if (err < 0)
e9edcee0 4851 return err;
0afe5f89 4852 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4853 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4854 if (err < 0)
e9edcee0
TI
4855 return err;
4856 return 0;
4857}
4858
05f5f477
TI
4859static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4860{
4861 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4862 return (pincap & AC_PINCAP_IN) != 0;
4863}
4864
e9edcee0 4865/* create playback/capture controls for input pins */
05f5f477
TI
4866static int alc_auto_create_input_ctls(struct hda_codec *codec,
4867 const struct auto_pin_cfg *cfg,
4868 hda_nid_t mixer,
4869 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4870{
05f5f477 4871 struct alc_spec *spec = codec->spec;
61b9b9b1 4872 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4873 int i, err, idx;
e9edcee0
TI
4874
4875 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4876 hda_nid_t pin;
4877
4878 pin = cfg->input_pins[i];
4879 if (!alc_is_input_pin(codec, pin))
4880 continue;
4881
4882 if (mixer) {
4883 idx = get_connection_index(codec, mixer, pin);
4884 if (idx >= 0) {
4885 err = new_analog_input(spec, pin,
4886 auto_pin_cfg_labels[i],
4887 idx, mixer);
4888 if (err < 0)
4889 return err;
4890 }
4891 }
4892
4893 if (!cap1)
4894 continue;
4895 idx = get_connection_index(codec, cap1, pin);
4896 if (idx < 0 && cap2)
4897 idx = get_connection_index(codec, cap2, pin);
4898 if (idx >= 0) {
f12ab1e0
TI
4899 imux->items[imux->num_items].label =
4900 auto_pin_cfg_labels[i];
05f5f477 4901 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4902 imux->num_items++;
4903 }
4904 }
4905 return 0;
4906}
4907
05f5f477
TI
4908static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4909 const struct auto_pin_cfg *cfg)
4910{
4911 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4912}
4913
f6c7e546
TI
4914static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4915 unsigned int pin_type)
4916{
4917 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4918 pin_type);
4919 /* unmute pin */
d260cdf6
TI
4920 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4921 AMP_OUT_UNMUTE);
f6c7e546
TI
4922}
4923
df694daa
KY
4924static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4925 hda_nid_t nid, int pin_type,
e9edcee0
TI
4926 int dac_idx)
4927{
f6c7e546 4928 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4929 /* need the manual connection? */
4930 if (alc880_is_multi_pin(nid)) {
4931 struct alc_spec *spec = codec->spec;
4932 int idx = alc880_multi_pin_idx(nid);
4933 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4934 AC_VERB_SET_CONNECT_SEL,
4935 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4936 }
4937}
4938
baba8ee9
TI
4939static int get_pin_type(int line_out_type)
4940{
4941 if (line_out_type == AUTO_PIN_HP_OUT)
4942 return PIN_HP;
4943 else
4944 return PIN_OUT;
4945}
4946
e9edcee0
TI
4947static void alc880_auto_init_multi_out(struct hda_codec *codec)
4948{
4949 struct alc_spec *spec = codec->spec;
4950 int i;
ea1fb29a 4951
e9edcee0
TI
4952 for (i = 0; i < spec->autocfg.line_outs; i++) {
4953 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4954 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4955 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4956 }
4957}
4958
8d88bc3d 4959static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4960{
4961 struct alc_spec *spec = codec->spec;
4962 hda_nid_t pin;
4963
82bc955f 4964 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4965 if (pin) /* connect to front */
4966 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4967 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4968 if (pin) /* connect to front */
4969 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4970}
4971
4972static void alc880_auto_init_analog_input(struct hda_codec *codec)
4973{
4974 struct alc_spec *spec = codec->spec;
4975 int i;
4976
4977 for (i = 0; i < AUTO_PIN_LAST; i++) {
4978 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 4979 if (alc_is_input_pin(codec, nid)) {
23f0c048 4980 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4981 if (nid != ALC880_PIN_CD_NID &&
4982 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4983 snd_hda_codec_write(codec, nid, 0,
4984 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4985 AMP_OUT_MUTE);
4986 }
4987 }
4988}
4989
7f311a46
TI
4990static void alc880_auto_init_input_src(struct hda_codec *codec)
4991{
4992 struct alc_spec *spec = codec->spec;
4993 int c;
4994
4995 for (c = 0; c < spec->num_adc_nids; c++) {
4996 unsigned int mux_idx;
4997 const struct hda_input_mux *imux;
4998 mux_idx = c >= spec->num_mux_defs ? 0 : c;
4999 imux = &spec->input_mux[mux_idx];
5000 if (!imux->num_items && mux_idx > 0)
5001 imux = &spec->input_mux[0];
5002 if (imux)
5003 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5004 AC_VERB_SET_CONNECT_SEL,
5005 imux->items[0].index);
5006 }
5007}
5008
e9edcee0 5009/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5010/* return 1 if successful, 0 if the proper config is not found,
5011 * or a negative error code
5012 */
e9edcee0
TI
5013static int alc880_parse_auto_config(struct hda_codec *codec)
5014{
5015 struct alc_spec *spec = codec->spec;
6a05ac4a 5016 int i, err;
df694daa 5017 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5018
f12ab1e0
TI
5019 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5020 alc880_ignore);
5021 if (err < 0)
e9edcee0 5022 return err;
f12ab1e0 5023 if (!spec->autocfg.line_outs)
e9edcee0 5024 return 0; /* can't find valid BIOS pin config */
df694daa 5025
f12ab1e0
TI
5026 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5027 if (err < 0)
5028 return err;
5029 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5030 if (err < 0)
5031 return err;
5032 err = alc880_auto_create_extra_out(spec,
5033 spec->autocfg.speaker_pins[0],
5034 "Speaker");
5035 if (err < 0)
5036 return err;
5037 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5038 "Headphone");
5039 if (err < 0)
5040 return err;
05f5f477 5041 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5042 if (err < 0)
e9edcee0
TI
5043 return err;
5044
5045 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5046
6a05ac4a
TI
5047 /* check multiple SPDIF-out (for recent codecs) */
5048 for (i = 0; i < spec->autocfg.dig_outs; i++) {
5049 hda_nid_t dig_nid;
5050 err = snd_hda_get_connections(codec,
5051 spec->autocfg.dig_out_pins[i],
5052 &dig_nid, 1);
5053 if (err < 0)
5054 continue;
5055 if (!i)
5056 spec->multiout.dig_out_nid = dig_nid;
5057 else {
5058 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 5059 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
6a05ac4a 5060 break;
71121d9f 5061 spec->slave_dig_outs[i - 1] = dig_nid;
6a05ac4a
TI
5062 }
5063 }
e9edcee0
TI
5064 if (spec->autocfg.dig_in_pin)
5065 spec->dig_in_nid = ALC880_DIGIN_NID;
5066
603c4019 5067 if (spec->kctls.list)
d88897ea 5068 add_mixer(spec, spec->kctls.list);
e9edcee0 5069
d88897ea 5070 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5071
a1e8d2da 5072 spec->num_mux_defs = 1;
61b9b9b1 5073 spec->input_mux = &spec->private_imux[0];
e9edcee0 5074
6227cdce 5075 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5076
e9edcee0
TI
5077 return 1;
5078}
5079
ae6b813a
TI
5080/* additional initialization for auto-configuration model */
5081static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5082{
f6c7e546 5083 struct alc_spec *spec = codec->spec;
e9edcee0 5084 alc880_auto_init_multi_out(codec);
8d88bc3d 5085 alc880_auto_init_extra_out(codec);
e9edcee0 5086 alc880_auto_init_analog_input(codec);
7f311a46 5087 alc880_auto_init_input_src(codec);
f6c7e546 5088 if (spec->unsol_event)
7fb0d78f 5089 alc_inithook(codec);
e9edcee0
TI
5090}
5091
b59bdf3b
TI
5092/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5093 * one of two digital mic pins, e.g. on ALC272
5094 */
5095static void fixup_automic_adc(struct hda_codec *codec)
5096{
5097 struct alc_spec *spec = codec->spec;
5098 int i;
5099
5100 for (i = 0; i < spec->num_adc_nids; i++) {
5101 hda_nid_t cap = spec->capsrc_nids ?
5102 spec->capsrc_nids[i] : spec->adc_nids[i];
5103 int iidx, eidx;
5104
5105 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5106 if (iidx < 0)
5107 continue;
5108 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5109 if (eidx < 0)
5110 continue;
5111 spec->int_mic.mux_idx = iidx;
5112 spec->ext_mic.mux_idx = eidx;
5113 if (spec->capsrc_nids)
5114 spec->capsrc_nids += i;
5115 spec->adc_nids += i;
5116 spec->num_adc_nids = 1;
5117 return;
5118 }
5119 snd_printd(KERN_INFO "hda_codec: %s: "
5120 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5121 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5122 spec->auto_mic = 0; /* disable auto-mic to be sure */
5123}
5124
840b64c0
TI
5125/* set the default connection to that pin */
5126static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5127{
5128 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5129 int i;
5130
eaa9b3a7
TI
5131 for (i = 0; i < spec->num_adc_nids; i++) {
5132 hda_nid_t cap = spec->capsrc_nids ?
5133 spec->capsrc_nids[i] : spec->adc_nids[i];
5134 int idx;
5135
5136 idx = get_connection_index(codec, cap, pin);
5137 if (idx < 0)
5138 continue;
eaa9b3a7
TI
5139 /* select or unmute this route */
5140 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5141 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5142 HDA_AMP_MUTE, 0);
5143 } else {
5144 snd_hda_codec_write_cache(codec, cap, 0,
5145 AC_VERB_SET_CONNECT_SEL, idx);
5146 }
840b64c0
TI
5147 return i; /* return the found index */
5148 }
5149 return -1; /* not found */
5150}
5151
5152/* choose the ADC/MUX containing the input pin and initialize the setup */
5153static void fixup_single_adc(struct hda_codec *codec)
5154{
5155 struct alc_spec *spec = codec->spec;
5156 hda_nid_t pin = 0;
5157 int i;
5158
5159 /* search for the input pin; there must be only one */
5160 for (i = 0; i < AUTO_PIN_LAST; i++) {
5161 if (spec->autocfg.input_pins[i]) {
5162 pin = spec->autocfg.input_pins[i];
5163 break;
5164 }
5165 }
5166 if (!pin)
eaa9b3a7 5167 return;
840b64c0
TI
5168 i = init_capsrc_for_pin(codec, pin);
5169 if (i >= 0) {
5170 /* use only this ADC */
5171 if (spec->capsrc_nids)
5172 spec->capsrc_nids += i;
5173 spec->adc_nids += i;
5174 spec->num_adc_nids = 1;
eaa9b3a7
TI
5175 }
5176}
5177
840b64c0
TI
5178/* initialize dual adcs */
5179static void fixup_dual_adc_switch(struct hda_codec *codec)
5180{
5181 struct alc_spec *spec = codec->spec;
5182 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5183 init_capsrc_for_pin(codec, spec->int_mic.pin);
5184}
5185
b59bdf3b 5186static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5187{
b59bdf3b 5188 struct alc_spec *spec = codec->spec;
a23b688f
TI
5189 static struct snd_kcontrol_new *caps[2][3] = {
5190 { alc_capture_mixer_nosrc1,
5191 alc_capture_mixer_nosrc2,
5192 alc_capture_mixer_nosrc3 },
5193 { alc_capture_mixer1,
5194 alc_capture_mixer2,
5195 alc_capture_mixer3 },
f9e336f6 5196 };
a23b688f 5197 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5198 int mux = 0;
840b64c0
TI
5199 int num_adcs = spec->num_adc_nids;
5200 if (spec->dual_adc_switch)
5201 fixup_dual_adc_switch(codec);
5202 else if (spec->auto_mic)
b59bdf3b 5203 fixup_automic_adc(codec);
eaa9b3a7
TI
5204 else if (spec->input_mux) {
5205 if (spec->input_mux->num_items > 1)
5206 mux = 1;
5207 else if (spec->input_mux->num_items == 1)
5208 fixup_single_adc(codec);
5209 }
840b64c0
TI
5210 if (spec->dual_adc_switch)
5211 num_adcs = 1;
5212 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5213 }
f9e336f6
TI
5214}
5215
6694635d
TI
5216/* fill adc_nids (and capsrc_nids) containing all active input pins */
5217static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5218 int num_nids)
5219{
5220 struct alc_spec *spec = codec->spec;
5221 int n;
5222 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5223
5224 for (n = 0; n < num_nids; n++) {
5225 hda_nid_t adc, cap;
5226 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5227 int nconns, i, j;
5228
5229 adc = nids[n];
5230 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5231 continue;
5232 cap = adc;
5233 nconns = snd_hda_get_connections(codec, cap, conn,
5234 ARRAY_SIZE(conn));
5235 if (nconns == 1) {
5236 cap = conn[0];
5237 nconns = snd_hda_get_connections(codec, cap, conn,
5238 ARRAY_SIZE(conn));
5239 }
5240 if (nconns <= 0)
5241 continue;
5242 if (!fallback_adc) {
5243 fallback_adc = adc;
5244 fallback_cap = cap;
5245 }
5246 for (i = 0; i < AUTO_PIN_LAST; i++) {
5247 hda_nid_t nid = spec->autocfg.input_pins[i];
5248 if (!nid)
5249 continue;
5250 for (j = 0; j < nconns; j++) {
5251 if (conn[j] == nid)
5252 break;
5253 }
5254 if (j >= nconns)
5255 break;
5256 }
5257 if (i >= AUTO_PIN_LAST) {
5258 int num_adcs = spec->num_adc_nids;
5259 spec->private_adc_nids[num_adcs] = adc;
5260 spec->private_capsrc_nids[num_adcs] = cap;
5261 spec->num_adc_nids++;
5262 spec->adc_nids = spec->private_adc_nids;
5263 if (adc != cap)
5264 spec->capsrc_nids = spec->private_capsrc_nids;
5265 }
5266 }
5267 if (!spec->num_adc_nids) {
5268 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5269 " using fallback 0x%x\n",
5270 codec->chip_name, fallback_adc);
6694635d
TI
5271 spec->private_adc_nids[0] = fallback_adc;
5272 spec->adc_nids = spec->private_adc_nids;
5273 if (fallback_adc != fallback_cap) {
5274 spec->private_capsrc_nids[0] = fallback_cap;
5275 spec->capsrc_nids = spec->private_adc_nids;
5276 }
5277 }
5278}
5279
67d634c0 5280#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5281#define set_beep_amp(spec, nid, idx, dir) \
5282 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5283
5284static struct snd_pci_quirk beep_white_list[] = {
5285 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5286 {}
5287};
5288
5289static inline int has_cdefine_beep(struct hda_codec *codec)
5290{
5291 struct alc_spec *spec = codec->spec;
5292 const struct snd_pci_quirk *q;
5293 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5294 if (q)
5295 return q->value;
5296 return spec->cdefine.enable_pcbeep;
5297}
67d634c0
TI
5298#else
5299#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5300#define has_cdefine_beep(codec) 0
67d634c0 5301#endif
45bdd1c1
TI
5302
5303/*
5304 * OK, here we have finally the patch for ALC880
5305 */
5306
1da177e4
LT
5307static int patch_alc880(struct hda_codec *codec)
5308{
5309 struct alc_spec *spec;
5310 int board_config;
df694daa 5311 int err;
1da177e4 5312
e560d8d8 5313 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5314 if (spec == NULL)
5315 return -ENOMEM;
5316
5317 codec->spec = spec;
5318
f5fcc13c
TI
5319 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5320 alc880_models,
5321 alc880_cfg_tbl);
5322 if (board_config < 0) {
9a11f1aa
TI
5323 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5324 codec->chip_name);
e9edcee0 5325 board_config = ALC880_AUTO;
1da177e4 5326 }
1da177e4 5327
e9edcee0
TI
5328 if (board_config == ALC880_AUTO) {
5329 /* automatic parse from the BIOS config */
5330 err = alc880_parse_auto_config(codec);
5331 if (err < 0) {
5332 alc_free(codec);
5333 return err;
f12ab1e0 5334 } else if (!err) {
9c7f852e
TI
5335 printk(KERN_INFO
5336 "hda_codec: Cannot set up configuration "
5337 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5338 board_config = ALC880_3ST;
5339 }
1da177e4
LT
5340 }
5341
680cd536
KK
5342 err = snd_hda_attach_beep_device(codec, 0x1);
5343 if (err < 0) {
5344 alc_free(codec);
5345 return err;
5346 }
5347
df694daa 5348 if (board_config != ALC880_AUTO)
e9c364c0 5349 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5350
1da177e4
LT
5351 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5352 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5353 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5354
1da177e4
LT
5355 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5356 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5357
f12ab1e0 5358 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5359 /* check whether NID 0x07 is valid */
54d17403 5360 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5361 /* get type */
a22d543a 5362 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5363 if (wcap != AC_WID_AUD_IN) {
5364 spec->adc_nids = alc880_adc_nids_alt;
5365 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5366 } else {
5367 spec->adc_nids = alc880_adc_nids;
5368 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5369 }
5370 }
b59bdf3b 5371 set_capture_mixer(codec);
45bdd1c1 5372 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5373
2134ea4f
TI
5374 spec->vmaster_nid = 0x0c;
5375
1da177e4 5376 codec->patch_ops = alc_patch_ops;
e9edcee0 5377 if (board_config == ALC880_AUTO)
ae6b813a 5378 spec->init_hook = alc880_auto_init;
cb53c626
TI
5379#ifdef CONFIG_SND_HDA_POWER_SAVE
5380 if (!spec->loopback.amplist)
5381 spec->loopback.amplist = alc880_loopbacks;
5382#endif
1da177e4
LT
5383
5384 return 0;
5385}
5386
e9edcee0 5387
1da177e4
LT
5388/*
5389 * ALC260 support
5390 */
5391
e9edcee0
TI
5392static hda_nid_t alc260_dac_nids[1] = {
5393 /* front */
5394 0x02,
5395};
5396
5397static hda_nid_t alc260_adc_nids[1] = {
5398 /* ADC0 */
5399 0x04,
5400};
5401
df694daa 5402static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5403 /* ADC1 */
5404 0x05,
5405};
5406
d57fdac0
JW
5407/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5408 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5409 */
5410static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5411 /* ADC0, ADC1 */
5412 0x04, 0x05
5413};
5414
e9edcee0
TI
5415#define ALC260_DIGOUT_NID 0x03
5416#define ALC260_DIGIN_NID 0x06
5417
5418static struct hda_input_mux alc260_capture_source = {
5419 .num_items = 4,
5420 .items = {
5421 { "Mic", 0x0 },
5422 { "Front Mic", 0x1 },
5423 { "Line", 0x2 },
5424 { "CD", 0x4 },
5425 },
5426};
5427
17e7aec6 5428/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5429 * headphone jack and the internal CD lines since these are the only pins at
5430 * which audio can appear. For flexibility, also allow the option of
5431 * recording the mixer output on the second ADC (ADC0 doesn't have a
5432 * connection to the mixer output).
a9430dd8 5433 */
a1e8d2da
JW
5434static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5435 {
5436 .num_items = 3,
5437 .items = {
5438 { "Mic/Line", 0x0 },
5439 { "CD", 0x4 },
5440 { "Headphone", 0x2 },
5441 },
a9430dd8 5442 },
a1e8d2da
JW
5443 {
5444 .num_items = 4,
5445 .items = {
5446 { "Mic/Line", 0x0 },
5447 { "CD", 0x4 },
5448 { "Headphone", 0x2 },
5449 { "Mixer", 0x5 },
5450 },
5451 },
5452
a9430dd8
JW
5453};
5454
a1e8d2da
JW
5455/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5456 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5457 */
a1e8d2da
JW
5458static struct hda_input_mux alc260_acer_capture_sources[2] = {
5459 {
5460 .num_items = 4,
5461 .items = {
5462 { "Mic", 0x0 },
5463 { "Line", 0x2 },
5464 { "CD", 0x4 },
5465 { "Headphone", 0x5 },
5466 },
5467 },
5468 {
5469 .num_items = 5,
5470 .items = {
5471 { "Mic", 0x0 },
5472 { "Line", 0x2 },
5473 { "CD", 0x4 },
5474 { "Headphone", 0x6 },
5475 { "Mixer", 0x5 },
5476 },
0bfc90e9
JW
5477 },
5478};
cc959489
MS
5479
5480/* Maxdata Favorit 100XS */
5481static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5482 {
5483 .num_items = 2,
5484 .items = {
5485 { "Line/Mic", 0x0 },
5486 { "CD", 0x4 },
5487 },
5488 },
5489 {
5490 .num_items = 3,
5491 .items = {
5492 { "Line/Mic", 0x0 },
5493 { "CD", 0x4 },
5494 { "Mixer", 0x5 },
5495 },
5496 },
5497};
5498
1da177e4
LT
5499/*
5500 * This is just place-holder, so there's something for alc_build_pcms to look
5501 * at when it calculates the maximum number of channels. ALC260 has no mixer
5502 * element which allows changing the channel mode, so the verb list is
5503 * never used.
5504 */
d2a6d7dc 5505static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5506 { 2, NULL },
5507};
5508
df694daa
KY
5509
5510/* Mixer combinations
5511 *
5512 * basic: base_output + input + pc_beep + capture
5513 * HP: base_output + input + capture_alt
5514 * HP_3013: hp_3013 + input + capture
5515 * fujitsu: fujitsu + capture
0bfc90e9 5516 * acer: acer + capture
df694daa
KY
5517 */
5518
5519static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5520 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5521 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5522 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5523 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5524 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5525 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5526 { } /* end */
f12ab1e0 5527};
1da177e4 5528
df694daa 5529static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5530 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5531 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5532 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5533 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5535 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5536 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5537 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5538 { } /* end */
5539};
5540
bec15c3a
TI
5541/* update HP, line and mono out pins according to the master switch */
5542static void alc260_hp_master_update(struct hda_codec *codec,
5543 hda_nid_t hp, hda_nid_t line,
5544 hda_nid_t mono)
5545{
5546 struct alc_spec *spec = codec->spec;
5547 unsigned int val = spec->master_sw ? PIN_HP : 0;
5548 /* change HP and line-out pins */
30cde0aa 5549 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5550 val);
30cde0aa 5551 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5552 val);
5553 /* mono (speaker) depending on the HP jack sense */
5554 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5555 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5556 val);
5557}
5558
5559static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5560 struct snd_ctl_elem_value *ucontrol)
5561{
5562 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5563 struct alc_spec *spec = codec->spec;
5564 *ucontrol->value.integer.value = spec->master_sw;
5565 return 0;
5566}
5567
5568static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5569 struct snd_ctl_elem_value *ucontrol)
5570{
5571 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5572 struct alc_spec *spec = codec->spec;
5573 int val = !!*ucontrol->value.integer.value;
5574 hda_nid_t hp, line, mono;
5575
5576 if (val == spec->master_sw)
5577 return 0;
5578 spec->master_sw = val;
5579 hp = (kcontrol->private_value >> 16) & 0xff;
5580 line = (kcontrol->private_value >> 8) & 0xff;
5581 mono = kcontrol->private_value & 0xff;
5582 alc260_hp_master_update(codec, hp, line, mono);
5583 return 1;
5584}
5585
5586static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5587 {
5588 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5589 .name = "Master Playback Switch",
5b0cb1d8 5590 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5591 .info = snd_ctl_boolean_mono_info,
5592 .get = alc260_hp_master_sw_get,
5593 .put = alc260_hp_master_sw_put,
5594 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5595 },
5596 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5597 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5598 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5599 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5600 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5601 HDA_OUTPUT),
5602 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5603 { } /* end */
5604};
5605
5606static struct hda_verb alc260_hp_unsol_verbs[] = {
5607 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5608 {},
5609};
5610
5611static void alc260_hp_automute(struct hda_codec *codec)
5612{
5613 struct alc_spec *spec = codec->spec;
bec15c3a 5614
864f92be 5615 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5616 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5617}
5618
5619static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5620{
5621 if ((res >> 26) == ALC880_HP_EVENT)
5622 alc260_hp_automute(codec);
5623}
5624
df694daa 5625static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5626 {
5627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5628 .name = "Master Playback Switch",
5b0cb1d8 5629 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5630 .info = snd_ctl_boolean_mono_info,
5631 .get = alc260_hp_master_sw_get,
5632 .put = alc260_hp_master_sw_put,
30cde0aa 5633 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5634 },
df694daa
KY
5635 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5636 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5637 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5638 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5639 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5640 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5641 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5642 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5643 { } /* end */
5644};
5645
3f878308
KY
5646static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5647 .ops = &snd_hda_bind_vol,
5648 .values = {
5649 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5650 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5651 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5652 0
5653 },
5654};
5655
5656static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5657 .ops = &snd_hda_bind_sw,
5658 .values = {
5659 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5660 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5661 0
5662 },
5663};
5664
5665static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5666 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5667 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5668 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5669 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5670 { } /* end */
5671};
5672
bec15c3a
TI
5673static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5674 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5675 {},
5676};
5677
5678static void alc260_hp_3013_automute(struct hda_codec *codec)
5679{
5680 struct alc_spec *spec = codec->spec;
bec15c3a 5681
864f92be 5682 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5683 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5684}
5685
5686static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5687 unsigned int res)
5688{
5689 if ((res >> 26) == ALC880_HP_EVENT)
5690 alc260_hp_3013_automute(codec);
5691}
5692
3f878308
KY
5693static void alc260_hp_3012_automute(struct hda_codec *codec)
5694{
864f92be 5695 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5696
3f878308
KY
5697 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5698 bits);
5699 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5700 bits);
5701 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5702 bits);
5703}
5704
5705static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5706 unsigned int res)
5707{
5708 if ((res >> 26) == ALC880_HP_EVENT)
5709 alc260_hp_3012_automute(codec);
5710}
5711
5712/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5713 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5714 */
c8b6bf9b 5715static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5716 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5717 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5718 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5719 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5720 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5721 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5722 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5723 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5724 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5725 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5726 { } /* end */
5727};
5728
a1e8d2da
JW
5729/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5730 * versions of the ALC260 don't act on requests to enable mic bias from NID
5731 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5732 * datasheet doesn't mention this restriction. At this stage it's not clear
5733 * whether this behaviour is intentional or is a hardware bug in chip
5734 * revisions available in early 2006. Therefore for now allow the
5735 * "Headphone Jack Mode" control to span all choices, but if it turns out
5736 * that the lack of mic bias for this NID is intentional we could change the
5737 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5738 *
5739 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5740 * don't appear to make the mic bias available from the "line" jack, even
5741 * though the NID used for this jack (0x14) can supply it. The theory is
5742 * that perhaps Acer have included blocking capacitors between the ALC260
5743 * and the output jack. If this turns out to be the case for all such
5744 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5745 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5746 *
5747 * The C20x Tablet series have a mono internal speaker which is controlled
5748 * via the chip's Mono sum widget and pin complex, so include the necessary
5749 * controls for such models. On models without a "mono speaker" the control
5750 * won't do anything.
a1e8d2da 5751 */
0bfc90e9
JW
5752static struct snd_kcontrol_new alc260_acer_mixer[] = {
5753 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5754 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5755 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5756 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5757 HDA_OUTPUT),
31bffaa9 5758 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5759 HDA_INPUT),
0bfc90e9
JW
5760 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5761 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5763 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5764 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5765 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5766 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5767 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5768 { } /* end */
5769};
5770
cc959489
MS
5771/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5772 */
5773static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5774 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5775 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5776 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5777 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5778 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5779 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5780 { } /* end */
5781};
5782
bc9f98a9
KY
5783/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5784 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5785 */
5786static struct snd_kcontrol_new alc260_will_mixer[] = {
5787 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5788 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5790 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5791 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5792 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5793 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5794 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5795 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5796 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5797 { } /* end */
5798};
5799
5800/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5801 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5802 */
5803static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5807 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5808 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5809 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5810 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5811 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5812 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5813 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5814 { } /* end */
5815};
5816
df694daa
KY
5817/*
5818 * initialization verbs
5819 */
1da177e4
LT
5820static struct hda_verb alc260_init_verbs[] = {
5821 /* Line In pin widget for input */
05acb863 5822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5823 /* CD pin widget for input */
05acb863 5824 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5825 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5826 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5827 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5828 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5829 /* LINE-2 is used for line-out in rear */
05acb863 5830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5831 /* select line-out */
fd56f2db 5832 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5833 /* LINE-OUT pin */
05acb863 5834 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5835 /* enable HP */
05acb863 5836 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5837 /* enable Mono */
05acb863
TI
5838 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5839 /* mute capture amp left and right */
16ded525 5840 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5841 /* set connection select to line in (default select for this ADC) */
5842 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5843 /* mute capture amp left and right */
5844 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5845 /* set connection select to line in (default select for this ADC) */
5846 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5847 /* set vol=0 Line-Out mixer amp left and right */
5848 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5849 /* unmute pin widget amp left and right (no gain on this amp) */
5850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5851 /* set vol=0 HP mixer amp left and right */
5852 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5853 /* unmute pin widget amp left and right (no gain on this amp) */
5854 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5855 /* set vol=0 Mono mixer amp left and right */
5856 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5857 /* unmute pin widget amp left and right (no gain on this amp) */
5858 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5859 /* unmute LINE-2 out pin */
5860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5861 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5862 * Line In 2 = 0x03
5863 */
cb53c626
TI
5864 /* mute analog inputs */
5865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5866 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5870 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5871 /* mute Front out path */
5872 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5873 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5874 /* mute Headphone out path */
5875 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5877 /* mute Mono out path */
5878 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5880 { }
5881};
5882
474167d6 5883#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5884static struct hda_verb alc260_hp_init_verbs[] = {
5885 /* Headphone and output */
5886 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5887 /* mono output */
5888 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5889 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5890 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5891 /* Mic2 (front panel) pin widget for input and vref at 80% */
5892 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5893 /* Line In pin widget for input */
5894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5895 /* Line-2 pin widget for output */
5896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5897 /* CD pin widget for input */
5898 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5899 /* unmute amp left and right */
5900 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5901 /* set connection select to line in (default select for this ADC) */
5902 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5903 /* unmute Line-Out mixer amp left and right (volume = 0) */
5904 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5905 /* mute pin widget amp left and right (no gain on this amp) */
5906 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5907 /* unmute HP mixer amp left and right (volume = 0) */
5908 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5909 /* mute pin widget amp left and right (no gain on this amp) */
5910 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5911 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5912 * Line In 2 = 0x03
5913 */
cb53c626
TI
5914 /* mute analog inputs */
5915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5920 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5921 /* Unmute Front out path */
5922 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5924 /* Unmute Headphone out path */
5925 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5927 /* Unmute Mono out path */
5928 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5930 { }
5931};
474167d6 5932#endif
df694daa
KY
5933
5934static struct hda_verb alc260_hp_3013_init_verbs[] = {
5935 /* Line out and output */
5936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5937 /* mono output */
5938 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5939 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5940 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5941 /* Mic2 (front panel) pin widget for input and vref at 80% */
5942 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5943 /* Line In pin widget for input */
5944 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5945 /* Headphone pin widget for output */
5946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5947 /* CD pin widget for input */
5948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5949 /* unmute amp left and right */
5950 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5951 /* set connection select to line in (default select for this ADC) */
5952 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5953 /* unmute Line-Out mixer amp left and right (volume = 0) */
5954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5955 /* mute pin widget amp left and right (no gain on this amp) */
5956 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5957 /* unmute HP mixer amp left and right (volume = 0) */
5958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5959 /* mute pin widget amp left and right (no gain on this amp) */
5960 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5961 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5962 * Line In 2 = 0x03
5963 */
cb53c626
TI
5964 /* mute analog inputs */
5965 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5970 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5971 /* Unmute Front out path */
5972 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5974 /* Unmute Headphone out path */
5975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5977 /* Unmute Mono out path */
5978 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5980 { }
5981};
5982
a9430dd8 5983/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5984 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5985 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5986 */
5987static struct hda_verb alc260_fujitsu_init_verbs[] = {
5988 /* Disable all GPIOs */
5989 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5990 /* Internal speaker is connected to headphone pin */
5991 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5992 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5994 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5995 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5996 /* Ensure all other unused pins are disabled and muted. */
5997 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5999 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6000 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6001 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6002 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6004 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6005
6006 /* Disable digital (SPDIF) pins */
6007 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6008 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6009
ea1fb29a 6010 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6011 * when acting as an output.
6012 */
6013 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6014
f7ace40d 6015 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6025
f7ace40d
JW
6026 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6027 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6028 /* Unmute Line1 pin widget output buffer since it starts as an output.
6029 * If the pin mode is changed by the user the pin mode control will
6030 * take care of enabling the pin's input/output buffers as needed.
6031 * Therefore there's no need to enable the input buffer at this
6032 * stage.
cdcd9268 6033 */
f7ace40d 6034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6035 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6036 * mixer ctrl)
6037 */
f7ace40d
JW
6038 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6039
6040 /* Mute capture amp left and right */
6041 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6042 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6043 * in (on mic1 pin)
6044 */
6045 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6046
6047 /* Do the same for the second ADC: mute capture input amp and
6048 * set ADC connection to line in (on mic1 pin)
6049 */
6050 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6051 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6052
6053 /* Mute all inputs to mixer widget (even unconnected ones) */
6054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6062
6063 { }
a9430dd8
JW
6064};
6065
0bfc90e9
JW
6066/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6067 * similar laptops (adapted from Fujitsu init verbs).
6068 */
6069static struct hda_verb alc260_acer_init_verbs[] = {
6070 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6071 * the headphone jack. Turn this on and rely on the standard mute
6072 * methods whenever the user wants to turn these outputs off.
6073 */
6074 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6075 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6076 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6077 /* Internal speaker/Headphone jack is connected to Line-out pin */
6078 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6079 /* Internal microphone/Mic jack is connected to Mic1 pin */
6080 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6081 /* Line In jack is connected to Line1 pin */
6082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6083 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6084 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6085 /* Ensure all other unused pins are disabled and muted. */
6086 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6087 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6088 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6089 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6092 /* Disable digital (SPDIF) pins */
6093 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6094 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6095
ea1fb29a 6096 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6097 * bus when acting as outputs.
6098 */
6099 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6100 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6101
6102 /* Start with output sum widgets muted and their output gains at min */
6103 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6104 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6105 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6107 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6109 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6110 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6111 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6112
f12ab1e0
TI
6113 /* Unmute Line-out pin widget amp left and right
6114 * (no equiv mixer ctrl)
6115 */
0bfc90e9 6116 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6117 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6118 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6119 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6120 * inputs. If the pin mode is changed by the user the pin mode control
6121 * will take care of enabling the pin's input/output buffers as needed.
6122 * Therefore there's no need to enable the input buffer at this
6123 * stage.
6124 */
6125 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6126 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6127
6128 /* Mute capture amp left and right */
6129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6130 /* Set ADC connection select to match default mixer setting - mic
6131 * (on mic1 pin)
6132 */
6133 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6134
6135 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6136 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6137 */
6138 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6139 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6140
6141 /* Mute all inputs to mixer widget (even unconnected ones) */
6142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6146 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6147 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6148 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6150
6151 { }
6152};
6153
cc959489
MS
6154/* Initialisation sequence for Maxdata Favorit 100XS
6155 * (adapted from Acer init verbs).
6156 */
6157static struct hda_verb alc260_favorit100_init_verbs[] = {
6158 /* GPIO 0 enables the output jack.
6159 * Turn this on and rely on the standard mute
6160 * methods whenever the user wants to turn these outputs off.
6161 */
6162 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6163 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6164 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6165 /* Line/Mic input jack is connected to Mic1 pin */
6166 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6167 /* Ensure all other unused pins are disabled and muted. */
6168 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6169 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6170 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6171 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6172 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6173 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6174 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6175 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6178 /* Disable digital (SPDIF) pins */
6179 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6180 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6181
6182 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6183 * bus when acting as outputs.
6184 */
6185 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6186 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6187
6188 /* Start with output sum widgets muted and their output gains at min */
6189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6190 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6191 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6193 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6194 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6195 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6196 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6197 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6198
6199 /* Unmute Line-out pin widget amp left and right
6200 * (no equiv mixer ctrl)
6201 */
6202 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6203 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6204 * inputs. If the pin mode is changed by the user the pin mode control
6205 * will take care of enabling the pin's input/output buffers as needed.
6206 * Therefore there's no need to enable the input buffer at this
6207 * stage.
6208 */
6209 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6210
6211 /* Mute capture amp left and right */
6212 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6213 /* Set ADC connection select to match default mixer setting - mic
6214 * (on mic1 pin)
6215 */
6216 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6217
6218 /* Do similar with the second ADC: mute capture input amp and
6219 * set ADC connection to mic to match ALSA's default state.
6220 */
6221 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6222 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6223
6224 /* Mute all inputs to mixer widget (even unconnected ones) */
6225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6233
6234 { }
6235};
6236
bc9f98a9
KY
6237static struct hda_verb alc260_will_verbs[] = {
6238 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6239 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6240 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6241 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6242 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6243 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6244 {}
6245};
6246
6247static struct hda_verb alc260_replacer_672v_verbs[] = {
6248 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6249 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6250 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6251
6252 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6253 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6254 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6255
6256 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6257 {}
6258};
6259
6260/* toggle speaker-output according to the hp-jack state */
6261static void alc260_replacer_672v_automute(struct hda_codec *codec)
6262{
6263 unsigned int present;
6264
6265 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6266 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6267 if (present) {
82beb8fd
TI
6268 snd_hda_codec_write_cache(codec, 0x01, 0,
6269 AC_VERB_SET_GPIO_DATA, 1);
6270 snd_hda_codec_write_cache(codec, 0x0f, 0,
6271 AC_VERB_SET_PIN_WIDGET_CONTROL,
6272 PIN_HP);
bc9f98a9 6273 } else {
82beb8fd
TI
6274 snd_hda_codec_write_cache(codec, 0x01, 0,
6275 AC_VERB_SET_GPIO_DATA, 0);
6276 snd_hda_codec_write_cache(codec, 0x0f, 0,
6277 AC_VERB_SET_PIN_WIDGET_CONTROL,
6278 PIN_OUT);
bc9f98a9
KY
6279 }
6280}
6281
6282static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6283 unsigned int res)
6284{
6285 if ((res >> 26) == ALC880_HP_EVENT)
6286 alc260_replacer_672v_automute(codec);
6287}
6288
3f878308
KY
6289static struct hda_verb alc260_hp_dc7600_verbs[] = {
6290 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6291 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6292 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6293 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6294 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6296 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6297 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6298 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6300 {}
6301};
6302
7cf51e48
JW
6303/* Test configuration for debugging, modelled after the ALC880 test
6304 * configuration.
6305 */
6306#ifdef CONFIG_SND_DEBUG
6307static hda_nid_t alc260_test_dac_nids[1] = {
6308 0x02,
6309};
6310static hda_nid_t alc260_test_adc_nids[2] = {
6311 0x04, 0x05,
6312};
a1e8d2da 6313/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6314 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6315 * is NID 0x04.
17e7aec6 6316 */
a1e8d2da
JW
6317static struct hda_input_mux alc260_test_capture_sources[2] = {
6318 {
6319 .num_items = 7,
6320 .items = {
6321 { "MIC1 pin", 0x0 },
6322 { "MIC2 pin", 0x1 },
6323 { "LINE1 pin", 0x2 },
6324 { "LINE2 pin", 0x3 },
6325 { "CD pin", 0x4 },
6326 { "LINE-OUT pin", 0x5 },
6327 { "HP-OUT pin", 0x6 },
6328 },
6329 },
6330 {
6331 .num_items = 8,
6332 .items = {
6333 { "MIC1 pin", 0x0 },
6334 { "MIC2 pin", 0x1 },
6335 { "LINE1 pin", 0x2 },
6336 { "LINE2 pin", 0x3 },
6337 { "CD pin", 0x4 },
6338 { "Mixer", 0x5 },
6339 { "LINE-OUT pin", 0x6 },
6340 { "HP-OUT pin", 0x7 },
6341 },
7cf51e48
JW
6342 },
6343};
6344static struct snd_kcontrol_new alc260_test_mixer[] = {
6345 /* Output driver widgets */
6346 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6347 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6348 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6349 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6350 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6351 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6352
a1e8d2da
JW
6353 /* Modes for retasking pin widgets
6354 * Note: the ALC260 doesn't seem to act on requests to enable mic
6355 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6356 * mention this restriction. At this stage it's not clear whether
6357 * this behaviour is intentional or is a hardware bug in chip
6358 * revisions available at least up until early 2006. Therefore for
6359 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6360 * choices, but if it turns out that the lack of mic bias for these
6361 * NIDs is intentional we could change their modes from
6362 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6363 */
7cf51e48
JW
6364 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6365 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6366 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6367 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6368 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6369 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6370
6371 /* Loopback mixer controls */
6372 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6373 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6374 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6375 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6376 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6377 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6378 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6379 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6380 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6381 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6382 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6383 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6384 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6385 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6386
6387 /* Controls for GPIO pins, assuming they are configured as outputs */
6388 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6389 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6390 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6391 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6392
92621f13
JW
6393 /* Switches to allow the digital IO pins to be enabled. The datasheet
6394 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6395 * make this output available should provide clarification.
92621f13
JW
6396 */
6397 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6398 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6399
f8225f6d
JW
6400 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6401 * this output to turn on an external amplifier.
6402 */
6403 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6404 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6405
7cf51e48
JW
6406 { } /* end */
6407};
6408static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6409 /* Enable all GPIOs as outputs with an initial value of 0 */
6410 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6411 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6412 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6413
7cf51e48
JW
6414 /* Enable retasking pins as output, initially without power amp */
6415 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6416 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6419 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6420 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6421
92621f13
JW
6422 /* Disable digital (SPDIF) pins initially, but users can enable
6423 * them via a mixer switch. In the case of SPDIF-out, this initverb
6424 * payload also sets the generation to 0, output to be in "consumer"
6425 * PCM format, copyright asserted, no pre-emphasis and no validity
6426 * control.
6427 */
7cf51e48
JW
6428 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6429 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6430
ea1fb29a 6431 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6432 * OUT1 sum bus when acting as an output.
6433 */
6434 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6435 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6436 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6437 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6438
6439 /* Start with output sum widgets muted and their output gains at min */
6440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6444 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6446 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6447 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6448 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6449
cdcd9268
JW
6450 /* Unmute retasking pin widget output buffers since the default
6451 * state appears to be output. As the pin mode is changed by the
6452 * user the pin mode control will take care of enabling the pin's
6453 * input/output buffers as needed.
6454 */
7cf51e48
JW
6455 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6456 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6459 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6460 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6461 /* Also unmute the mono-out pin widget */
6462 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6463
7cf51e48
JW
6464 /* Mute capture amp left and right */
6465 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6466 /* Set ADC connection select to match default mixer setting (mic1
6467 * pin)
7cf51e48
JW
6468 */
6469 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6470
6471 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6472 * set ADC connection to mic1 pin
7cf51e48
JW
6473 */
6474 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6475 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6476
6477 /* Mute all inputs to mixer widget (even unconnected ones) */
6478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6486
6487 { }
6488};
6489#endif
6490
6330079f
TI
6491#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6492#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6493
a3bcba38
TI
6494#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6495#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6496
df694daa
KY
6497/*
6498 * for BIOS auto-configuration
6499 */
16ded525 6500
df694daa 6501static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6502 const char *pfx, int *vol_bits)
df694daa
KY
6503{
6504 hda_nid_t nid_vol;
6505 unsigned long vol_val, sw_val;
df694daa
KY
6506 int err;
6507
6508 if (nid >= 0x0f && nid < 0x11) {
6509 nid_vol = nid - 0x7;
6510 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6511 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6512 } else if (nid == 0x11) {
6513 nid_vol = nid - 0x7;
6514 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6515 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6516 } else if (nid >= 0x12 && nid <= 0x15) {
6517 nid_vol = 0x08;
6518 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6519 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6520 } else
6521 return 0; /* N/A */
ea1fb29a 6522
863b4518
TI
6523 if (!(*vol_bits & (1 << nid_vol))) {
6524 /* first control for the volume widget */
0afe5f89 6525 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6526 if (err < 0)
6527 return err;
6528 *vol_bits |= (1 << nid_vol);
6529 }
0afe5f89 6530 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6531 if (err < 0)
df694daa
KY
6532 return err;
6533 return 1;
6534}
6535
6536/* add playback controls from the parsed DAC table */
6537static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6538 const struct auto_pin_cfg *cfg)
6539{
6540 hda_nid_t nid;
6541 int err;
863b4518 6542 int vols = 0;
df694daa
KY
6543
6544 spec->multiout.num_dacs = 1;
6545 spec->multiout.dac_nids = spec->private_dac_nids;
6546 spec->multiout.dac_nids[0] = 0x02;
6547
6548 nid = cfg->line_out_pins[0];
6549 if (nid) {
23112d6d
TI
6550 const char *pfx;
6551 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6552 pfx = "Master";
6553 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6554 pfx = "Speaker";
6555 else
6556 pfx = "Front";
6557 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6558 if (err < 0)
6559 return err;
6560 }
6561
82bc955f 6562 nid = cfg->speaker_pins[0];
df694daa 6563 if (nid) {
863b4518 6564 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6565 if (err < 0)
6566 return err;
6567 }
6568
eb06ed8f 6569 nid = cfg->hp_pins[0];
df694daa 6570 if (nid) {
863b4518
TI
6571 err = alc260_add_playback_controls(spec, nid, "Headphone",
6572 &vols);
df694daa
KY
6573 if (err < 0)
6574 return err;
6575 }
f12ab1e0 6576 return 0;
df694daa
KY
6577}
6578
6579/* create playback/capture controls for input pins */
05f5f477 6580static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6581 const struct auto_pin_cfg *cfg)
6582{
05f5f477 6583 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6584}
6585
6586static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6587 hda_nid_t nid, int pin_type,
6588 int sel_idx)
6589{
f6c7e546 6590 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6591 /* need the manual connection? */
6592 if (nid >= 0x12) {
6593 int idx = nid - 0x12;
6594 snd_hda_codec_write(codec, idx + 0x0b, 0,
6595 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6596 }
6597}
6598
6599static void alc260_auto_init_multi_out(struct hda_codec *codec)
6600{
6601 struct alc_spec *spec = codec->spec;
6602 hda_nid_t nid;
6603
f12ab1e0 6604 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6605 if (nid) {
6606 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6607 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6608 }
ea1fb29a 6609
82bc955f 6610 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6611 if (nid)
6612 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6613
eb06ed8f 6614 nid = spec->autocfg.hp_pins[0];
df694daa 6615 if (nid)
baba8ee9 6616 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6617}
df694daa
KY
6618
6619#define ALC260_PIN_CD_NID 0x16
6620static void alc260_auto_init_analog_input(struct hda_codec *codec)
6621{
6622 struct alc_spec *spec = codec->spec;
6623 int i;
6624
6625 for (i = 0; i < AUTO_PIN_LAST; i++) {
6626 hda_nid_t nid = spec->autocfg.input_pins[i];
6627 if (nid >= 0x12) {
23f0c048 6628 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6629 if (nid != ALC260_PIN_CD_NID &&
6630 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6631 snd_hda_codec_write(codec, nid, 0,
6632 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6633 AMP_OUT_MUTE);
6634 }
6635 }
6636}
6637
7f311a46
TI
6638#define alc260_auto_init_input_src alc880_auto_init_input_src
6639
df694daa
KY
6640/*
6641 * generic initialization of ADC, input mixers and output mixers
6642 */
6643static struct hda_verb alc260_volume_init_verbs[] = {
6644 /*
6645 * Unmute ADC0-1 and set the default input to mic-in
6646 */
6647 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6648 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6649 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6650 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6651
df694daa
KY
6652 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6653 * mixer widget
f12ab1e0
TI
6654 * Note: PASD motherboards uses the Line In 2 as the input for
6655 * front panel mic (mic 2)
df694daa
KY
6656 */
6657 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6658 /* mute analog inputs */
6659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6662 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6663 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6664
6665 /*
6666 * Set up output mixers (0x08 - 0x0a)
6667 */
6668 /* set vol=0 to output mixers */
6669 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6672 /* set up input amps for analog loopback */
6673 /* Amp Indices: DAC = 0, mixer = 1 */
6674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6676 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6678 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6679 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6680
df694daa
KY
6681 { }
6682};
6683
6684static int alc260_parse_auto_config(struct hda_codec *codec)
6685{
6686 struct alc_spec *spec = codec->spec;
df694daa
KY
6687 int err;
6688 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6689
f12ab1e0
TI
6690 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6691 alc260_ignore);
6692 if (err < 0)
df694daa 6693 return err;
f12ab1e0
TI
6694 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6695 if (err < 0)
4a471b7d 6696 return err;
603c4019 6697 if (!spec->kctls.list)
df694daa 6698 return 0; /* can't find valid BIOS pin config */
05f5f477 6699 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6700 if (err < 0)
df694daa
KY
6701 return err;
6702
6703 spec->multiout.max_channels = 2;
6704
0852d7a6 6705 if (spec->autocfg.dig_outs)
df694daa 6706 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6707 if (spec->kctls.list)
d88897ea 6708 add_mixer(spec, spec->kctls.list);
df694daa 6709
d88897ea 6710 add_verb(spec, alc260_volume_init_verbs);
df694daa 6711
a1e8d2da 6712 spec->num_mux_defs = 1;
61b9b9b1 6713 spec->input_mux = &spec->private_imux[0];
df694daa 6714
6227cdce 6715 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6716
df694daa
KY
6717 return 1;
6718}
6719
ae6b813a
TI
6720/* additional initialization for auto-configuration model */
6721static void alc260_auto_init(struct hda_codec *codec)
df694daa 6722{
f6c7e546 6723 struct alc_spec *spec = codec->spec;
df694daa
KY
6724 alc260_auto_init_multi_out(codec);
6725 alc260_auto_init_analog_input(codec);
7f311a46 6726 alc260_auto_init_input_src(codec);
f6c7e546 6727 if (spec->unsol_event)
7fb0d78f 6728 alc_inithook(codec);
df694daa
KY
6729}
6730
cb53c626
TI
6731#ifdef CONFIG_SND_HDA_POWER_SAVE
6732static struct hda_amp_list alc260_loopbacks[] = {
6733 { 0x07, HDA_INPUT, 0 },
6734 { 0x07, HDA_INPUT, 1 },
6735 { 0x07, HDA_INPUT, 2 },
6736 { 0x07, HDA_INPUT, 3 },
6737 { 0x07, HDA_INPUT, 4 },
6738 { } /* end */
6739};
6740#endif
6741
df694daa
KY
6742/*
6743 * ALC260 configurations
6744 */
f5fcc13c
TI
6745static const char *alc260_models[ALC260_MODEL_LAST] = {
6746 [ALC260_BASIC] = "basic",
6747 [ALC260_HP] = "hp",
6748 [ALC260_HP_3013] = "hp-3013",
2922c9af 6749 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6750 [ALC260_FUJITSU_S702X] = "fujitsu",
6751 [ALC260_ACER] = "acer",
bc9f98a9
KY
6752 [ALC260_WILL] = "will",
6753 [ALC260_REPLACER_672V] = "replacer",
cc959489 6754 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6755#ifdef CONFIG_SND_DEBUG
f5fcc13c 6756 [ALC260_TEST] = "test",
7cf51e48 6757#endif
f5fcc13c
TI
6758 [ALC260_AUTO] = "auto",
6759};
6760
6761static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6762 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6763 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6764 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6765 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6766 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6767 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6768 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6769 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6770 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6771 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6772 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6773 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6774 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6775 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6776 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6777 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6778 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6779 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6780 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6781 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6782 {}
6783};
6784
6785static struct alc_config_preset alc260_presets[] = {
6786 [ALC260_BASIC] = {
6787 .mixers = { alc260_base_output_mixer,
45bdd1c1 6788 alc260_input_mixer },
df694daa
KY
6789 .init_verbs = { alc260_init_verbs },
6790 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6791 .dac_nids = alc260_dac_nids,
f9e336f6 6792 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6793 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6794 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6795 .channel_mode = alc260_modes,
6796 .input_mux = &alc260_capture_source,
6797 },
6798 [ALC260_HP] = {
bec15c3a 6799 .mixers = { alc260_hp_output_mixer,
f9e336f6 6800 alc260_input_mixer },
bec15c3a
TI
6801 .init_verbs = { alc260_init_verbs,
6802 alc260_hp_unsol_verbs },
df694daa
KY
6803 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6804 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6805 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6806 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6807 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6808 .channel_mode = alc260_modes,
6809 .input_mux = &alc260_capture_source,
bec15c3a
TI
6810 .unsol_event = alc260_hp_unsol_event,
6811 .init_hook = alc260_hp_automute,
df694daa 6812 },
3f878308
KY
6813 [ALC260_HP_DC7600] = {
6814 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6815 alc260_input_mixer },
3f878308
KY
6816 .init_verbs = { alc260_init_verbs,
6817 alc260_hp_dc7600_verbs },
6818 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6819 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6820 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6821 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6822 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6823 .channel_mode = alc260_modes,
6824 .input_mux = &alc260_capture_source,
6825 .unsol_event = alc260_hp_3012_unsol_event,
6826 .init_hook = alc260_hp_3012_automute,
6827 },
df694daa
KY
6828 [ALC260_HP_3013] = {
6829 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6830 alc260_input_mixer },
bec15c3a
TI
6831 .init_verbs = { alc260_hp_3013_init_verbs,
6832 alc260_hp_3013_unsol_verbs },
df694daa
KY
6833 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6834 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6835 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6836 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6837 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6838 .channel_mode = alc260_modes,
6839 .input_mux = &alc260_capture_source,
bec15c3a
TI
6840 .unsol_event = alc260_hp_3013_unsol_event,
6841 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6842 },
6843 [ALC260_FUJITSU_S702X] = {
f9e336f6 6844 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6845 .init_verbs = { alc260_fujitsu_init_verbs },
6846 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6847 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6848 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6849 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6850 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6851 .channel_mode = alc260_modes,
a1e8d2da
JW
6852 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6853 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6854 },
0bfc90e9 6855 [ALC260_ACER] = {
f9e336f6 6856 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6857 .init_verbs = { alc260_acer_init_verbs },
6858 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6859 .dac_nids = alc260_dac_nids,
6860 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6861 .adc_nids = alc260_dual_adc_nids,
6862 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6863 .channel_mode = alc260_modes,
a1e8d2da
JW
6864 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6865 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6866 },
cc959489
MS
6867 [ALC260_FAVORIT100] = {
6868 .mixers = { alc260_favorit100_mixer },
6869 .init_verbs = { alc260_favorit100_init_verbs },
6870 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6871 .dac_nids = alc260_dac_nids,
6872 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6873 .adc_nids = alc260_dual_adc_nids,
6874 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6875 .channel_mode = alc260_modes,
6876 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6877 .input_mux = alc260_favorit100_capture_sources,
6878 },
bc9f98a9 6879 [ALC260_WILL] = {
f9e336f6 6880 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6881 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6882 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6883 .dac_nids = alc260_dac_nids,
6884 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6885 .adc_nids = alc260_adc_nids,
6886 .dig_out_nid = ALC260_DIGOUT_NID,
6887 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6888 .channel_mode = alc260_modes,
6889 .input_mux = &alc260_capture_source,
6890 },
6891 [ALC260_REPLACER_672V] = {
f9e336f6 6892 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6893 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6894 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6895 .dac_nids = alc260_dac_nids,
6896 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6897 .adc_nids = alc260_adc_nids,
6898 .dig_out_nid = ALC260_DIGOUT_NID,
6899 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6900 .channel_mode = alc260_modes,
6901 .input_mux = &alc260_capture_source,
6902 .unsol_event = alc260_replacer_672v_unsol_event,
6903 .init_hook = alc260_replacer_672v_automute,
6904 },
7cf51e48
JW
6905#ifdef CONFIG_SND_DEBUG
6906 [ALC260_TEST] = {
f9e336f6 6907 .mixers = { alc260_test_mixer },
7cf51e48
JW
6908 .init_verbs = { alc260_test_init_verbs },
6909 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6910 .dac_nids = alc260_test_dac_nids,
6911 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6912 .adc_nids = alc260_test_adc_nids,
6913 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6914 .channel_mode = alc260_modes,
a1e8d2da
JW
6915 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6916 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6917 },
6918#endif
df694daa
KY
6919};
6920
6921static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6922{
6923 struct alc_spec *spec;
df694daa 6924 int err, board_config;
1da177e4 6925
e560d8d8 6926 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6927 if (spec == NULL)
6928 return -ENOMEM;
6929
6930 codec->spec = spec;
6931
f5fcc13c
TI
6932 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6933 alc260_models,
6934 alc260_cfg_tbl);
6935 if (board_config < 0) {
9a11f1aa 6936 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6937 codec->chip_name);
df694daa 6938 board_config = ALC260_AUTO;
16ded525 6939 }
1da177e4 6940
df694daa
KY
6941 if (board_config == ALC260_AUTO) {
6942 /* automatic parse from the BIOS config */
6943 err = alc260_parse_auto_config(codec);
6944 if (err < 0) {
6945 alc_free(codec);
6946 return err;
f12ab1e0 6947 } else if (!err) {
9c7f852e
TI
6948 printk(KERN_INFO
6949 "hda_codec: Cannot set up configuration "
6950 "from BIOS. Using base mode...\n");
df694daa
KY
6951 board_config = ALC260_BASIC;
6952 }
a9430dd8 6953 }
e9edcee0 6954
680cd536
KK
6955 err = snd_hda_attach_beep_device(codec, 0x1);
6956 if (err < 0) {
6957 alc_free(codec);
6958 return err;
6959 }
6960
df694daa 6961 if (board_config != ALC260_AUTO)
e9c364c0 6962 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 6963
1da177e4
LT
6964 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6965 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6966
a3bcba38
TI
6967 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6968 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6969
4ef0ef19
TI
6970 if (!spec->adc_nids && spec->input_mux) {
6971 /* check whether NID 0x04 is valid */
6972 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 6973 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
6974 /* get type */
6975 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6976 spec->adc_nids = alc260_adc_nids_alt;
6977 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6978 } else {
6979 spec->adc_nids = alc260_adc_nids;
6980 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6981 }
6982 }
b59bdf3b 6983 set_capture_mixer(codec);
45bdd1c1 6984 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6985
2134ea4f
TI
6986 spec->vmaster_nid = 0x08;
6987
1da177e4 6988 codec->patch_ops = alc_patch_ops;
df694daa 6989 if (board_config == ALC260_AUTO)
ae6b813a 6990 spec->init_hook = alc260_auto_init;
cb53c626
TI
6991#ifdef CONFIG_SND_HDA_POWER_SAVE
6992 if (!spec->loopback.amplist)
6993 spec->loopback.amplist = alc260_loopbacks;
6994#endif
1da177e4
LT
6995
6996 return 0;
6997}
6998
e9edcee0 6999
1da177e4 7000/*
4953550a 7001 * ALC882/883/885/888/889 support
1da177e4
LT
7002 *
7003 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7004 * configuration. Each pin widget can choose any input DACs and a mixer.
7005 * Each ADC is connected from a mixer of all inputs. This makes possible
7006 * 6-channel independent captures.
7007 *
7008 * In addition, an independent DAC for the multi-playback (not used in this
7009 * driver yet).
7010 */
df694daa
KY
7011#define ALC882_DIGOUT_NID 0x06
7012#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7013#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7014#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7015#define ALC1200_DIGOUT_NID 0x10
7016
1da177e4 7017
d2a6d7dc 7018static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7019 { 8, NULL }
7020};
7021
4953550a 7022/* DACs */
1da177e4
LT
7023static hda_nid_t alc882_dac_nids[4] = {
7024 /* front, rear, clfe, rear_surr */
7025 0x02, 0x03, 0x04, 0x05
7026};
4953550a 7027#define alc883_dac_nids alc882_dac_nids
1da177e4 7028
4953550a 7029/* ADCs */
df694daa
KY
7030#define alc882_adc_nids alc880_adc_nids
7031#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7032#define alc883_adc_nids alc882_adc_nids_alt
7033static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7034static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7035#define alc889_adc_nids alc880_adc_nids
1da177e4 7036
e1406348
TI
7037static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7038static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7039#define alc883_capsrc_nids alc882_capsrc_nids_alt
7040static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7041#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7042
1da177e4
LT
7043/* input MUX */
7044/* FIXME: should be a matrix-type input source selection */
7045
7046static struct hda_input_mux alc882_capture_source = {
7047 .num_items = 4,
7048 .items = {
7049 { "Mic", 0x0 },
7050 { "Front Mic", 0x1 },
7051 { "Line", 0x2 },
7052 { "CD", 0x4 },
7053 },
7054};
41d5545d 7055
4953550a
TI
7056#define alc883_capture_source alc882_capture_source
7057
87a8c370
JK
7058static struct hda_input_mux alc889_capture_source = {
7059 .num_items = 3,
7060 .items = {
7061 { "Front Mic", 0x0 },
7062 { "Mic", 0x3 },
7063 { "Line", 0x2 },
7064 },
7065};
7066
41d5545d
KS
7067static struct hda_input_mux mb5_capture_source = {
7068 .num_items = 3,
7069 .items = {
7070 { "Mic", 0x1 },
b8f171e7 7071 { "Line", 0x7 },
41d5545d
KS
7072 { "CD", 0x4 },
7073 },
7074};
7075
e458b1fa
LY
7076static struct hda_input_mux macmini3_capture_source = {
7077 .num_items = 2,
7078 .items = {
7079 { "Line", 0x2 },
7080 { "CD", 0x4 },
7081 },
7082};
7083
4953550a
TI
7084static struct hda_input_mux alc883_3stack_6ch_intel = {
7085 .num_items = 4,
7086 .items = {
7087 { "Mic", 0x1 },
7088 { "Front Mic", 0x0 },
7089 { "Line", 0x2 },
7090 { "CD", 0x4 },
7091 },
7092};
7093
7094static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7095 .num_items = 2,
7096 .items = {
7097 { "Mic", 0x1 },
7098 { "Line", 0x2 },
7099 },
7100};
7101
7102static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7103 .num_items = 4,
7104 .items = {
7105 { "Mic", 0x0 },
7106 { "iMic", 0x1 },
7107 { "Line", 0x2 },
7108 { "CD", 0x4 },
7109 },
7110};
7111
7112static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7113 .num_items = 2,
7114 .items = {
7115 { "Mic", 0x0 },
7116 { "Int Mic", 0x1 },
7117 },
7118};
7119
7120static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7121 .num_items = 3,
7122 .items = {
7123 { "Mic", 0x0 },
7124 { "Front Mic", 0x1 },
7125 { "Line", 0x4 },
7126 },
7127};
7128
7129static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7130 .num_items = 2,
7131 .items = {
7132 { "Mic", 0x0 },
7133 { "Line", 0x2 },
7134 },
7135};
7136
7137static struct hda_input_mux alc889A_mb31_capture_source = {
7138 .num_items = 2,
7139 .items = {
7140 { "Mic", 0x0 },
7141 /* Front Mic (0x01) unused */
7142 { "Line", 0x2 },
7143 /* Line 2 (0x03) unused */
af901ca1 7144 /* CD (0x04) unused? */
4953550a
TI
7145 },
7146};
7147
b7cccc52
JM
7148static struct hda_input_mux alc889A_imac91_capture_source = {
7149 .num_items = 2,
7150 .items = {
7151 { "Mic", 0x01 },
7152 { "Line", 0x2 }, /* Not sure! */
7153 },
7154};
7155
4953550a
TI
7156/*
7157 * 2ch mode
7158 */
7159static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7160 { 2, NULL }
7161};
7162
272a527c
KY
7163/*
7164 * 2ch mode
7165 */
7166static struct hda_verb alc882_3ST_ch2_init[] = {
7167 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7168 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7169 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7170 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7171 { } /* end */
7172};
7173
4953550a
TI
7174/*
7175 * 4ch mode
7176 */
7177static struct hda_verb alc882_3ST_ch4_init[] = {
7178 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7179 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7180 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7181 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7182 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7183 { } /* end */
7184};
7185
272a527c
KY
7186/*
7187 * 6ch mode
7188 */
7189static struct hda_verb alc882_3ST_ch6_init[] = {
7190 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7191 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7192 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7193 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7194 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7195 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7196 { } /* end */
7197};
7198
4953550a 7199static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7200 { 2, alc882_3ST_ch2_init },
4953550a 7201 { 4, alc882_3ST_ch4_init },
272a527c
KY
7202 { 6, alc882_3ST_ch6_init },
7203};
7204
4953550a
TI
7205#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7206
a65cc60f 7207/*
7208 * 2ch mode
7209 */
7210static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7211 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7212 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7213 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7214 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7215 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7216 { } /* end */
7217};
7218
7219/*
7220 * 4ch mode
7221 */
7222static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7223 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7224 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7225 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7228 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7229 { } /* end */
7230};
7231
7232/*
7233 * 6ch mode
7234 */
7235static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7236 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
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_3ST_6ch_clevo_modes[3] = {
7247 { 2, alc883_3ST_ch2_clevo_init },
7248 { 4, alc883_3ST_ch4_clevo_init },
7249 { 6, alc883_3ST_ch6_clevo_init },
7250};
7251
7252
df694daa
KY
7253/*
7254 * 6ch mode
7255 */
7256static struct hda_verb alc882_sixstack_ch6_init[] = {
7257 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7258 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7259 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7260 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7261 { } /* end */
7262};
7263
7264/*
7265 * 8ch mode
7266 */
7267static struct hda_verb alc882_sixstack_ch8_init[] = {
7268 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7269 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7270 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7271 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7272 { } /* end */
7273};
7274
7275static struct hda_channel_mode alc882_sixstack_modes[2] = {
7276 { 6, alc882_sixstack_ch6_init },
7277 { 8, alc882_sixstack_ch8_init },
7278};
7279
76e6f5a9
RH
7280
7281/* Macbook Air 2,1 */
7282
7283static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7284 { 2, NULL },
7285};
7286
87350ad0 7287/*
def319f9 7288 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7289 */
7290
7291/*
7292 * 2ch mode
7293 */
7294static struct hda_verb alc885_mbp_ch2_init[] = {
7295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7296 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7297 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7298 { } /* end */
7299};
7300
7301/*
a3f730af 7302 * 4ch mode
87350ad0 7303 */
a3f730af 7304static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7305 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7307 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7308 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7310 { } /* end */
7311};
7312
a3f730af 7313static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7314 { 2, alc885_mbp_ch2_init },
a3f730af 7315 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7316};
7317
92b9de83
KS
7318/*
7319 * 2ch
7320 * Speakers/Woofer/HP = Front
7321 * LineIn = Input
7322 */
7323static struct hda_verb alc885_mb5_ch2_init[] = {
7324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7326 { } /* end */
7327};
7328
7329/*
7330 * 6ch mode
7331 * Speakers/HP = Front
7332 * Woofer = LFE
7333 * LineIn = Surround
7334 */
7335static struct hda_verb alc885_mb5_ch6_init[] = {
7336 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7337 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7339 { } /* end */
7340};
7341
7342static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7343 { 2, alc885_mb5_ch2_init },
7344 { 6, alc885_mb5_ch6_init },
7345};
87350ad0 7346
d01aecdf 7347#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7348
7349/*
7350 * 2ch mode
7351 */
7352static struct hda_verb alc883_4ST_ch2_init[] = {
7353 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7354 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7355 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7356 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7357 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7358 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7359 { } /* end */
7360};
7361
7362/*
7363 * 4ch mode
7364 */
7365static struct hda_verb alc883_4ST_ch4_init[] = {
7366 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7367 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7368 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7369 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7370 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7371 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7372 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7373 { } /* end */
7374};
7375
7376/*
7377 * 6ch mode
7378 */
7379static struct hda_verb alc883_4ST_ch6_init[] = {
7380 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7381 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7382 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7383 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7384 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7385 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7386 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7387 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7388 { } /* end */
7389};
7390
7391/*
7392 * 8ch mode
7393 */
7394static struct hda_verb alc883_4ST_ch8_init[] = {
7395 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7396 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7397 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7398 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7399 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7400 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7401 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7402 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7403 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7404 { } /* end */
7405};
7406
7407static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7408 { 2, alc883_4ST_ch2_init },
7409 { 4, alc883_4ST_ch4_init },
7410 { 6, alc883_4ST_ch6_init },
7411 { 8, alc883_4ST_ch8_init },
7412};
7413
7414
7415/*
7416 * 2ch mode
7417 */
7418static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7419 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7420 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7421 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7422 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7423 { } /* end */
7424};
7425
7426/*
7427 * 4ch mode
7428 */
7429static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7430 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7431 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7432 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7433 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7434 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7435 { } /* end */
7436};
7437
7438/*
7439 * 6ch mode
7440 */
7441static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7442 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7443 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7444 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7445 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7446 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7447 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7448 { } /* end */
7449};
7450
7451static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7452 { 2, alc883_3ST_ch2_intel_init },
7453 { 4, alc883_3ST_ch4_intel_init },
7454 { 6, alc883_3ST_ch6_intel_init },
7455};
7456
dd7714c9
WF
7457/*
7458 * 2ch mode
7459 */
7460static struct hda_verb alc889_ch2_intel_init[] = {
7461 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7462 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7463 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7464 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7465 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7466 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7467 { } /* end */
7468};
7469
87a8c370
JK
7470/*
7471 * 6ch mode
7472 */
7473static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7474 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7475 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7476 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7477 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7478 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7479 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7480 { } /* end */
7481};
7482
7483/*
7484 * 8ch mode
7485 */
7486static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7487 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7488 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7489 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7490 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7491 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7492 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7493 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7494 { } /* end */
7495};
7496
dd7714c9
WF
7497static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7498 { 2, alc889_ch2_intel_init },
87a8c370
JK
7499 { 6, alc889_ch6_intel_init },
7500 { 8, alc889_ch8_intel_init },
7501};
7502
4953550a
TI
7503/*
7504 * 6ch mode
7505 */
7506static struct hda_verb alc883_sixstack_ch6_init[] = {
7507 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7508 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7509 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7510 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7511 { } /* end */
7512};
7513
7514/*
7515 * 8ch mode
7516 */
7517static struct hda_verb alc883_sixstack_ch8_init[] = {
7518 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7519 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7520 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7521 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7522 { } /* end */
7523};
7524
7525static struct hda_channel_mode alc883_sixstack_modes[2] = {
7526 { 6, alc883_sixstack_ch6_init },
7527 { 8, alc883_sixstack_ch8_init },
7528};
7529
7530
1da177e4
LT
7531/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7532 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7533 */
c8b6bf9b 7534static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7535 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7536 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7537 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7538 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7539 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7540 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7541 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7542 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7543 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7544 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7549 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7550 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7551 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7553 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7554 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7555 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7556 { } /* end */
7557};
7558
76e6f5a9
RH
7559/* Macbook Air 2,1 same control for HP and internal Speaker */
7560
7561static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7562 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7563 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7564 { }
7565};
7566
7567
87350ad0 7568static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7569 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7570 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7571 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7572 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7573 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7574 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7575 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7577 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7578 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7580 { } /* end */
7581};
41d5545d
KS
7582
7583static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7584 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7585 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7586 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7587 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7588 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7589 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7590 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7591 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7592 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7593 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7594 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7595 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7596 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7597 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7598 { } /* end */
7599};
92b9de83 7600
e458b1fa
LY
7601static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7603 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7604 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7605 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7606 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7607 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7608 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7609 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7610 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7611 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7612 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7613 { } /* end */
7614};
7615
4b7e1803 7616static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7617 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7618 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7619 { } /* end */
7620};
7621
7622
bdd148a3
KY
7623static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7624 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7625 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7633 { } /* end */
7634};
7635
272a527c
KY
7636static struct snd_kcontrol_new alc882_targa_mixer[] = {
7637 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7638 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7640 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7641 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7646 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7647 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7648 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7649 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7650 { } /* end */
7651};
7652
7653/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7654 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7655 */
7656static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7657 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7658 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7659 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7660 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7661 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7662 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7663 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7664 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7665 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7666 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7669 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7670 { } /* end */
7671};
7672
914759b7
TI
7673static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7674 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7675 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7677 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7678 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7679 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7680 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7682 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7683 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7684 { } /* end */
7685};
7686
df694daa
KY
7687static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7688 {
7689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7690 .name = "Channel Mode",
7691 .info = alc_ch_mode_info,
7692 .get = alc_ch_mode_get,
7693 .put = alc_ch_mode_put,
7694 },
7695 { } /* end */
7696};
7697
4953550a 7698static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7699 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7702 /* Rear mixer */
05acb863
TI
7703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7704 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7705 /* CLFE mixer */
05acb863
TI
7706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7708 /* Side mixer */
05acb863
TI
7709 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7710 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7711
e9edcee0 7712 /* Front Pin: output 0 (0x0c) */
05acb863 7713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7715 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7716 /* Rear Pin: output 1 (0x0d) */
05acb863 7717 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7719 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7720 /* CLFE Pin: output 2 (0x0e) */
05acb863 7721 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7722 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7723 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7724 /* Side Pin: output 3 (0x0f) */
05acb863 7725 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7726 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7727 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7728 /* Mic (rear) pin: input vref at 80% */
16ded525 7729 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7730 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7731 /* Front Mic pin: input vref at 80% */
16ded525 7732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7733 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7734 /* Line In pin: input */
05acb863 7735 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7736 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7737 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7738 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7739 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7740 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7741 /* CD pin widget for input */
05acb863 7742 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7743
7744 /* FIXME: use matrix-type input source selection */
7745 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7746 /* Input mixer2 */
05acb863 7747 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7748 /* Input mixer3 */
05acb863 7749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7750 /* ADC2: mute amp left and right */
7751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7752 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7753 /* ADC3: mute amp left and right */
7754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7755 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7756
7757 { }
7758};
7759
4953550a
TI
7760static struct hda_verb alc882_adc1_init_verbs[] = {
7761 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7765 {0x24, 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 { }
7770};
7771
4b146cb0
TI
7772static struct hda_verb alc882_eapd_verbs[] = {
7773 /* change to EAPD mode */
7774 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7775 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7776 { }
4b146cb0
TI
7777};
7778
87a8c370
JK
7779static struct hda_verb alc889_eapd_verbs[] = {
7780 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7781 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7782 { }
7783};
7784
6732bd0d
WF
7785static struct hda_verb alc_hp15_unsol_verbs[] = {
7786 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7787 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7788 {}
7789};
87a8c370
JK
7790
7791static struct hda_verb alc885_init_verbs[] = {
7792 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7793 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7795 /* Rear mixer */
88102f3f
KY
7796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7797 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7798 /* CLFE mixer */
88102f3f
KY
7799 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7800 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7801 /* Side mixer */
88102f3f
KY
7802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7804
7805 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7809 /* Front Pin: output 0 (0x0c) */
7810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7811 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7812 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7813 /* Rear Pin: output 1 (0x0d) */
7814 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7815 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7816 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7817 /* CLFE Pin: output 2 (0x0e) */
7818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7820 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7821 /* Side Pin: output 3 (0x0f) */
7822 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7823 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7824 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7825 /* Mic (rear) pin: input vref at 80% */
7826 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7827 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7828 /* Front Mic pin: input vref at 80% */
7829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7831 /* Line In pin: input */
7832 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7833 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7834
7835 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7836 /* Input mixer1 */
88102f3f 7837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7838 /* Input mixer2 */
7839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7840 /* Input mixer3 */
88102f3f 7841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7842 /* ADC2: mute amp left and right */
7843 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7844 /* ADC3: mute amp left and right */
7845 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7846
7847 { }
7848};
7849
7850static struct hda_verb alc885_init_input_verbs[] = {
7851 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7852 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7853 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7854 { }
7855};
7856
7857
7858/* Unmute Selector 24h and set the default input to front mic */
7859static struct hda_verb alc889_init_input_verbs[] = {
7860 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7861 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7862 { }
7863};
7864
7865
4953550a
TI
7866#define alc883_init_verbs alc882_base_init_verbs
7867
9102cd1c
TD
7868/* Mac Pro test */
7869static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7870 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7871 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7873 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7874 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7875 /* FIXME: this looks suspicious...
d355c82a
JK
7876 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7877 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7878 */
9102cd1c
TD
7879 { } /* end */
7880};
7881
7882static struct hda_verb alc882_macpro_init_verbs[] = {
7883 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7884 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7887 /* Front Pin: output 0 (0x0c) */
7888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7890 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7891 /* Front Mic pin: input vref at 80% */
7892 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7893 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7894 /* Speaker: output */
7895 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7896 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7897 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7898 /* Headphone output (output 0 - 0x0c) */
7899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7901 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7902
7903 /* FIXME: use matrix-type input source selection */
7904 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7905 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7907 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7908 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7910 /* Input mixer2 */
7911 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7912 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7913 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7914 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7915 /* Input mixer3 */
7916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7918 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7919 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7920 /* ADC1: mute amp left and right */
7921 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7922 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7923 /* ADC2: mute amp left and right */
7924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7925 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7926 /* ADC3: mute amp left and right */
7927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7928 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7929
7930 { }
7931};
f12ab1e0 7932
41d5545d
KS
7933/* Macbook 5,1 */
7934static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7935 /* DACs */
7936 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7937 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7938 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7939 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7940 /* Front mixer */
41d5545d
KS
7941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7944 /* Surround mixer */
7945 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7948 /* LFE mixer */
7949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7951 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7952 /* HP mixer */
7953 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7954 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7955 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7956 /* Front Pin (0x0c) */
41d5545d
KS
7957 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
7959 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7960 /* LFE Pin (0x0e) */
7961 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7962 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7963 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7964 /* HP Pin (0x0f) */
41d5545d
KS
7965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 7967 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 7968 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
7969 /* Front Mic pin: input vref at 80% */
7970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7971 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7972 /* Line In pin */
7973 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7974 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7975
b8f171e7
AM
7976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
7977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
7978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
7979 { }
7980};
7981
e458b1fa
LY
7982/* Macmini 3,1 */
7983static struct hda_verb alc885_macmini3_init_verbs[] = {
7984 /* DACs */
7985 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7986 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7987 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7988 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7989 /* Front mixer */
7990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7992 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7993 /* Surround mixer */
7994 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7995 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7996 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7997 /* LFE mixer */
7998 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7999 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8000 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8001 /* HP mixer */
8002 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8005 /* Front Pin (0x0c) */
8006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8007 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8009 /* LFE Pin (0x0e) */
8010 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8011 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8012 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8013 /* HP Pin (0x0f) */
8014 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8015 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8016 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8017 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8018 /* Line In pin */
8019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8021
8022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8026 { }
8027};
8028
76e6f5a9
RH
8029
8030static struct hda_verb alc885_mba21_init_verbs[] = {
8031 /*Internal and HP Speaker Mixer*/
8032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8034 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8035 /*Internal Speaker Pin (0x0c)*/
8036 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8038 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8039 /* HP Pin: output 0 (0x0e) */
8040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8041 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8042 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8043 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8044 /* Line in (is hp when jack connected)*/
8045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8047
8048 { }
8049 };
8050
8051
87350ad0
TI
8052/* Macbook Pro rev3 */
8053static struct hda_verb alc885_mbp3_init_verbs[] = {
8054 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8057 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8058 /* Rear mixer */
8059 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8060 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8061 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8062 /* HP mixer */
8063 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8066 /* Front Pin: output 0 (0x0c) */
8067 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8069 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8070 /* HP Pin: output 0 (0x0e) */
87350ad0 8071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8072 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8073 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8074 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8075 /* Mic (rear) pin: input vref at 80% */
8076 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8077 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8078 /* Front Mic pin: input vref at 80% */
8079 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8080 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8081 /* Line In pin: use output 1 when in LineOut mode */
8082 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8083 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8084 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8085
8086 /* FIXME: use matrix-type input source selection */
8087 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8088 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8089 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8091 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8092 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8093 /* Input mixer2 */
8094 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8095 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8096 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8097 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8098 /* Input mixer3 */
8099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8103 /* ADC1: mute amp left and right */
8104 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8105 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8106 /* ADC2: mute amp left and right */
8107 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8109 /* ADC3: mute amp left and right */
8110 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8111 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8112
8113 { }
8114};
8115
4b7e1803
JM
8116/* iMac 9,1 */
8117static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8118 /* Internal Speaker Pin (0x0c) */
8119 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8120 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8121 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8122 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8123 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8124 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8125 /* HP Pin: Rear */
4b7e1803
JM
8126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8128 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8129 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8130 /* Line in Rear */
8131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8132 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8133 /* Front Mic pin: input vref at 80% */
8134 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8136 /* Rear mixer */
8137 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8138 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8139 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8140 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8141 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8142 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8143 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8144 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8145 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8147 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8149 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8150 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8154 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8159 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8161 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8162 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8163 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8164 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8165 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8166 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8167 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8168 { }
8169};
8170
c54728d8
NF
8171/* iMac 24 mixer. */
8172static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8173 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8174 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8175 { } /* end */
8176};
8177
8178/* iMac 24 init verbs. */
8179static struct hda_verb alc885_imac24_init_verbs[] = {
8180 /* Internal speakers: output 0 (0x0c) */
8181 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8182 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8183 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8184 /* Internal speakers: output 0 (0x0c) */
8185 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8186 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8187 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8188 /* Headphone: output 0 (0x0c) */
8189 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8190 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8191 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8192 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8193 /* Front Mic: input vref at 80% */
8194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8196 { }
8197};
8198
8199/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8200static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8201{
a9fd4f3f 8202 struct alc_spec *spec = codec->spec;
c54728d8 8203
a9fd4f3f
TI
8204 spec->autocfg.hp_pins[0] = 0x14;
8205 spec->autocfg.speaker_pins[0] = 0x18;
8206 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8207}
8208
9d54f08b
TI
8209#define alc885_mb5_setup alc885_imac24_setup
8210#define alc885_macmini3_setup alc885_imac24_setup
8211
76e6f5a9
RH
8212/* Macbook Air 2,1 */
8213static void alc885_mba21_setup(struct hda_codec *codec)
8214{
8215 struct alc_spec *spec = codec->spec;
8216
8217 spec->autocfg.hp_pins[0] = 0x14;
8218 spec->autocfg.speaker_pins[0] = 0x18;
8219}
8220
8221
8222
4f5d1706 8223static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8224{
a9fd4f3f 8225 struct alc_spec *spec = codec->spec;
87350ad0 8226
a9fd4f3f
TI
8227 spec->autocfg.hp_pins[0] = 0x15;
8228 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8229}
8230
9d54f08b 8231static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8232{
9d54f08b 8233 struct alc_spec *spec = codec->spec;
4b7e1803 8234
9d54f08b 8235 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8236 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8237 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8238}
87350ad0 8239
272a527c
KY
8240static struct hda_verb alc882_targa_verbs[] = {
8241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8243
8244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8245 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8246
272a527c
KY
8247 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8248 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8249 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8250
8251 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8252 { } /* end */
8253};
8254
8255/* toggle speaker-output according to the hp-jack state */
8256static void alc882_targa_automute(struct hda_codec *codec)
8257{
a9fd4f3f
TI
8258 struct alc_spec *spec = codec->spec;
8259 alc_automute_amp(codec);
82beb8fd 8260 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8261 spec->jack_present ? 1 : 3);
8262}
8263
4f5d1706 8264static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8265{
8266 struct alc_spec *spec = codec->spec;
8267
8268 spec->autocfg.hp_pins[0] = 0x14;
8269 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8270}
8271
8272static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8273{
a9fd4f3f 8274 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8275 alc882_targa_automute(codec);
272a527c
KY
8276}
8277
8278static struct hda_verb alc882_asus_a7j_verbs[] = {
8279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8281
8282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8284 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8285
272a527c
KY
8286 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8287 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8289
8290 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8291 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8292 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8293 { } /* end */
8294};
8295
914759b7
TI
8296static struct hda_verb alc882_asus_a7m_verbs[] = {
8297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8299
8300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8302 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8303
914759b7
TI
8304 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8305 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8306 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8307
8308 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8309 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8311 { } /* end */
8312};
8313
9102cd1c
TD
8314static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8315{
8316 unsigned int gpiostate, gpiomask, gpiodir;
8317
8318 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8319 AC_VERB_GET_GPIO_DATA, 0);
8320
8321 if (!muted)
8322 gpiostate |= (1 << pin);
8323 else
8324 gpiostate &= ~(1 << pin);
8325
8326 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8327 AC_VERB_GET_GPIO_MASK, 0);
8328 gpiomask |= (1 << pin);
8329
8330 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8331 AC_VERB_GET_GPIO_DIRECTION, 0);
8332 gpiodir |= (1 << pin);
8333
8334
8335 snd_hda_codec_write(codec, codec->afg, 0,
8336 AC_VERB_SET_GPIO_MASK, gpiomask);
8337 snd_hda_codec_write(codec, codec->afg, 0,
8338 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8339
8340 msleep(1);
8341
8342 snd_hda_codec_write(codec, codec->afg, 0,
8343 AC_VERB_SET_GPIO_DATA, gpiostate);
8344}
8345
7debbe51
TI
8346/* set up GPIO at initialization */
8347static void alc885_macpro_init_hook(struct hda_codec *codec)
8348{
8349 alc882_gpio_mute(codec, 0, 0);
8350 alc882_gpio_mute(codec, 1, 0);
8351}
8352
8353/* set up GPIO and update auto-muting at initialization */
8354static void alc885_imac24_init_hook(struct hda_codec *codec)
8355{
8356 alc885_macpro_init_hook(codec);
4f5d1706 8357 alc_automute_amp(codec);
7debbe51
TI
8358}
8359
df694daa
KY
8360/*
8361 * generic initialization of ADC, input mixers and output mixers
8362 */
4953550a 8363static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8364 /*
8365 * Unmute ADC0-2 and set the default input to mic-in
8366 */
4953550a
TI
8367 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8368 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8369 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8370 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8371
4953550a
TI
8372 /*
8373 * Set up output mixers (0x0c - 0x0f)
8374 */
8375 /* set vol=0 to output mixers */
8376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8377 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8380 /* set up input amps for analog loopback */
8381 /* Amp Indices: DAC = 0, mixer = 1 */
8382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8384 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8386 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8390 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8391 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8392
4953550a
TI
8393 /* FIXME: use matrix-type input source selection */
8394 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8395 /* Input mixer2 */
88102f3f 8396 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8397 /* Input mixer3 */
88102f3f 8398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8399 { }
9c7f852e
TI
8400};
8401
eb4c41d3
TS
8402/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8403static struct hda_verb alc889A_mb31_ch2_init[] = {
8404 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8405 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8406 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8407 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8408 { } /* end */
8409};
8410
8411/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8412static struct hda_verb alc889A_mb31_ch4_init[] = {
8413 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8414 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8415 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8416 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8417 { } /* end */
8418};
8419
8420/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8421static struct hda_verb alc889A_mb31_ch5_init[] = {
8422 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8426 { } /* end */
8427};
8428
8429/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8430static struct hda_verb alc889A_mb31_ch6_init[] = {
8431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8432 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8433 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8435 { } /* end */
8436};
8437
8438static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8439 { 2, alc889A_mb31_ch2_init },
8440 { 4, alc889A_mb31_ch4_init },
8441 { 5, alc889A_mb31_ch5_init },
8442 { 6, alc889A_mb31_ch6_init },
8443};
8444
b373bdeb
AN
8445static struct hda_verb alc883_medion_eapd_verbs[] = {
8446 /* eanable EAPD on medion laptop */
8447 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8448 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8449 { }
8450};
8451
4953550a 8452#define alc883_base_mixer alc882_base_mixer
834be88d 8453
a8848bd6
AS
8454static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8455 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8456 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8457 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8459 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8460 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8463 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8464 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8465 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8466 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8468 { } /* end */
8469};
8470
0c4cc443 8471static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8472 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8473 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8474 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8475 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8477 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8479 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8480 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8481 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8482 { } /* end */
8483};
8484
fb97dc67
J
8485static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8486 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8487 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8488 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8489 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8491 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
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),
fb97dc67
J
8496 { } /* end */
8497};
8498
9c7f852e
TI
8499static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8503 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8504 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8505 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8506 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8511 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8513 { } /* end */
8514};
df694daa 8515
9c7f852e
TI
8516static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8518 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8519 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8520 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8521 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8522 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8523 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8524 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8525 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8526 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8527 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8528 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8529 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8530 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8531 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8532 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8533 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8534 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8535 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8536 { } /* end */
8537};
8538
17bba1b7
J
8539static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8542 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8543 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8544 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8545 HDA_OUTPUT),
8546 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8548 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8555 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8556 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8558 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8559 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8560 { } /* end */
8561};
8562
87a8c370
JK
8563static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8564 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8565 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8566 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8567 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8568 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8569 HDA_OUTPUT),
8570 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8571 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8572 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8573 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8574 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8576 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8577 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8579 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8581 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8582 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8583 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8584 { } /* end */
8585};
8586
d1d985f0 8587static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8588 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8589 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8590 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8591 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8592 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8593 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8594 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8595 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8597 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8598 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8599 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8600 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8602 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8604 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8605 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8607 { } /* end */
8608};
8609
c259249f 8610static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8611 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8612 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8613 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8614 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8615 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8616 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8617 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8618 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8619 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8620 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8621 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8622 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8623 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8624 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8626 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8628 { } /* end */
f12ab1e0 8629};
ccc656ce 8630
c259249f 8631static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8632 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8633 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8635 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8639 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8640 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8641 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8642 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8643 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8644 { } /* end */
f12ab1e0 8645};
ccc656ce 8646
b99dba34
TI
8647static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8648 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8649 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8650 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8651 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8652 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8653 { } /* end */
8654};
8655
bc9f98a9
KY
8656static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8657 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8658 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8659 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8660 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8661 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8663 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8665 { } /* end */
f12ab1e0 8666};
bc9f98a9 8667
272a527c
KY
8668static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8670 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8676 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8677 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8678 { } /* end */
8679};
8680
8681static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8684 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8687 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8688 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8691 { } /* end */
ea1fb29a 8692};
272a527c 8693
7ad7b218
MC
8694static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8697 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8698 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8699 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8700 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8701 { } /* end */
8702};
8703
8704static struct hda_verb alc883_medion_wim2160_verbs[] = {
8705 /* Unmute front mixer */
8706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8708
8709 /* Set speaker pin to front mixer */
8710 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8711
8712 /* Init headphone pin */
8713 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8715 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8716 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8717
8718 { } /* end */
8719};
8720
8721/* toggle speaker-output according to the hp-jack state */
8722static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8723{
8724 struct alc_spec *spec = codec->spec;
8725
8726 spec->autocfg.hp_pins[0] = 0x1a;
8727 spec->autocfg.speaker_pins[0] = 0x15;
8728}
8729
2880a867 8730static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8731 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8732 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8733 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8734 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8735 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8737 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8738 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8739 { } /* end */
d1a991a6 8740};
2880a867 8741
d2fd4b09
TV
8742static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8743 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8744 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8745 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8746 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8747 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8748 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8749 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8750 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8751 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8752 { } /* end */
8753};
8754
e2757d5e
KY
8755static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8759 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8760 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8761 0x0d, 1, 0x0, HDA_OUTPUT),
8762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8765 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8766 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8767 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8768 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8769 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8770 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8772 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8773 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8774 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8775 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8776 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8777 { } /* end */
8778};
8779
eb4c41d3
TS
8780static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8781 /* Output mixers */
8782 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8783 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8784 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8785 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8786 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8787 HDA_OUTPUT),
8788 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8789 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8790 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8791 /* Output switches */
8792 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8793 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8794 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8795 /* Boost mixers */
8796 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8797 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8798 /* Input mixers */
8799 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8800 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8801 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8802 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8803 { } /* end */
8804};
8805
3e1647c5
GG
8806static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8807 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8808 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8809 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8811 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8813 { } /* end */
8814};
8815
e2757d5e
KY
8816static struct hda_bind_ctls alc883_bind_cap_vol = {
8817 .ops = &snd_hda_bind_vol,
8818 .values = {
8819 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8820 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8821 0
8822 },
8823};
8824
8825static struct hda_bind_ctls alc883_bind_cap_switch = {
8826 .ops = &snd_hda_bind_sw,
8827 .values = {
8828 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8829 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8830 0
8831 },
8832};
8833
8834static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8836 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8837 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8838 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8839 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8843 { } /* end */
8844};
df694daa 8845
4953550a
TI
8846static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8847 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8848 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8849 {
8850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8851 /* .name = "Capture Source", */
8852 .name = "Input Source",
8853 .count = 1,
8854 .info = alc_mux_enum_info,
8855 .get = alc_mux_enum_get,
8856 .put = alc_mux_enum_put,
8857 },
8858 { } /* end */
8859};
9c7f852e 8860
4953550a
TI
8861static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8862 {
8863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8864 .name = "Channel Mode",
8865 .info = alc_ch_mode_info,
8866 .get = alc_ch_mode_get,
8867 .put = alc_ch_mode_put,
8868 },
8869 { } /* end */
9c7f852e
TI
8870};
8871
a8848bd6 8872/* toggle speaker-output according to the hp-jack state */
4f5d1706 8873static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8874{
a9fd4f3f 8875 struct alc_spec *spec = codec->spec;
a8848bd6 8876
a9fd4f3f
TI
8877 spec->autocfg.hp_pins[0] = 0x15;
8878 spec->autocfg.speaker_pins[0] = 0x14;
8879 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8880}
8881
8882/* auto-toggle front mic */
8883/*
8884static void alc883_mitac_mic_automute(struct hda_codec *codec)
8885{
864f92be 8886 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8887
a8848bd6
AS
8888 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8889}
8890*/
8891
a8848bd6
AS
8892static struct hda_verb alc883_mitac_verbs[] = {
8893 /* HP */
8894 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8896 /* Subwoofer */
8897 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8898 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8899
8900 /* enable unsolicited event */
8901 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8902 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8903
8904 { } /* end */
8905};
8906
a65cc60f 8907static struct hda_verb alc883_clevo_m540r_verbs[] = {
8908 /* HP */
8909 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8910 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8911 /* Int speaker */
8912 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8913
8914 /* enable unsolicited event */
8915 /*
8916 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8917 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8918 */
8919
8920 { } /* end */
8921};
8922
0c4cc443 8923static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8924 /* HP */
8925 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8926 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8927 /* Int speaker */
8928 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8929 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8930
8931 /* enable unsolicited event */
8932 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8933 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8934
8935 { } /* end */
8936};
8937
fb97dc67
J
8938static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8939 /* HP */
8940 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8941 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8942 /* Subwoofer */
8943 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8944 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8945
8946 /* enable unsolicited event */
8947 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8948
8949 { } /* end */
8950};
8951
c259249f 8952static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8954 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8955
8956 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8957 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8958
64a8be74
DH
8959/* Connect Line-Out side jack (SPDIF) to Side */
8960 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8961 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8962 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8963/* Connect Mic jack to CLFE */
8964 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8965 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8966 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8967/* Connect Line-in jack to Surround */
8968 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8969 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8970 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8971/* Connect HP out jack to Front */
8972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8973 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8974 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
8975
8976 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
8977
8978 { } /* end */
8979};
8980
bc9f98a9
KY
8981static struct hda_verb alc883_lenovo_101e_verbs[] = {
8982 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8985 { } /* end */
8986};
8987
272a527c
KY
8988static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8989 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8991 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8992 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8993 { } /* end */
8994};
8995
8996static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8999 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9000 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9001 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9002 { } /* end */
9003};
9004
189609ae
KY
9005static struct hda_verb alc883_haier_w66_verbs[] = {
9006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9007 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9008
9009 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9010
9011 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9012 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9013 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9014 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9015 { } /* end */
9016};
9017
e2757d5e
KY
9018static struct hda_verb alc888_lenovo_sky_verbs[] = {
9019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9021 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9023 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9024 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9025 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9026 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9027 { } /* end */
9028};
9029
8718b700
HRK
9030static struct hda_verb alc888_6st_dell_verbs[] = {
9031 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9032 { }
9033};
9034
3e1647c5
GG
9035static struct hda_verb alc883_vaiott_verbs[] = {
9036 /* HP */
9037 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9039
9040 /* enable unsolicited event */
9041 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9042
9043 { } /* end */
9044};
9045
4f5d1706 9046static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9047{
a9fd4f3f 9048 struct alc_spec *spec = codec->spec;
8718b700 9049
a9fd4f3f
TI
9050 spec->autocfg.hp_pins[0] = 0x1b;
9051 spec->autocfg.speaker_pins[0] = 0x14;
9052 spec->autocfg.speaker_pins[1] = 0x16;
9053 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9054}
9055
4723c022 9056static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9057 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9058 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9059 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9060 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9061 { } /* end */
5795b9e6
CM
9062};
9063
3ea0d7cf
HRK
9064/*
9065 * 2ch mode
9066 */
4723c022 9067static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9070 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9071 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9072 { } /* end */
8341de60
CM
9073};
9074
3ea0d7cf
HRK
9075/*
9076 * 4ch mode
9077 */
9078static struct hda_verb alc888_3st_hp_4ch_init[] = {
9079 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9080 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9081 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9082 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9083 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9084 { } /* end */
9085};
9086
9087/*
9088 * 6ch mode
9089 */
4723c022 9090static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9091 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9092 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9093 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9094 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9095 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9096 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9097 { } /* end */
8341de60
CM
9098};
9099
3ea0d7cf 9100static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9101 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9102 { 4, alc888_3st_hp_4ch_init },
4723c022 9103 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9104};
9105
272a527c
KY
9106/* toggle front-jack and RCA according to the hp-jack state */
9107static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9108{
864f92be 9109 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9110
47fd830a
TI
9111 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9112 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9113 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9114 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9115}
9116
9117/* toggle RCA according to the front-jack state */
9118static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9119{
864f92be 9120 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9121
47fd830a
TI
9122 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9123 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9124}
47fd830a 9125
272a527c
KY
9126static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9127 unsigned int res)
9128{
9129 if ((res >> 26) == ALC880_HP_EVENT)
9130 alc888_lenovo_ms7195_front_automute(codec);
9131 if ((res >> 26) == ALC880_FRONT_EVENT)
9132 alc888_lenovo_ms7195_rca_automute(codec);
9133}
9134
9135static struct hda_verb alc883_medion_md2_verbs[] = {
9136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9138
9139 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9140
9141 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9142 { } /* end */
9143};
9144
9145/* toggle speaker-output according to the hp-jack state */
4f5d1706 9146static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9147{
a9fd4f3f 9148 struct alc_spec *spec = codec->spec;
272a527c 9149
a9fd4f3f
TI
9150 spec->autocfg.hp_pins[0] = 0x14;
9151 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9152}
9153
ccc656ce 9154/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9155#define alc883_targa_init_hook alc882_targa_init_hook
9156#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9157
0c4cc443
HRK
9158static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9159{
9160 unsigned int present;
9161
d56757ab 9162 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9163 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9164 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9165}
9166
4f5d1706 9167static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9168{
a9fd4f3f
TI
9169 struct alc_spec *spec = codec->spec;
9170
9171 spec->autocfg.hp_pins[0] = 0x15;
9172 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9173}
9174
9175static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9176{
a9fd4f3f 9177 alc_automute_amp(codec);
0c4cc443
HRK
9178 alc883_clevo_m720_mic_automute(codec);
9179}
9180
9181static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9182 unsigned int res)
9183{
0c4cc443 9184 switch (res >> 26) {
0c4cc443
HRK
9185 case ALC880_MIC_EVENT:
9186 alc883_clevo_m720_mic_automute(codec);
9187 break;
a9fd4f3f
TI
9188 default:
9189 alc_automute_amp_unsol_event(codec, res);
9190 break;
0c4cc443 9191 }
368c7a95
J
9192}
9193
fb97dc67 9194/* toggle speaker-output according to the hp-jack state */
4f5d1706 9195static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9196{
a9fd4f3f 9197 struct alc_spec *spec = codec->spec;
fb97dc67 9198
a9fd4f3f
TI
9199 spec->autocfg.hp_pins[0] = 0x14;
9200 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9201}
9202
4f5d1706 9203static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9204{
a9fd4f3f 9205 struct alc_spec *spec = codec->spec;
189609ae 9206
a9fd4f3f
TI
9207 spec->autocfg.hp_pins[0] = 0x1b;
9208 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9209}
9210
bc9f98a9
KY
9211static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9212{
864f92be 9213 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9214
47fd830a
TI
9215 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9216 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9217}
9218
9219static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9220{
864f92be 9221 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9222
47fd830a
TI
9223 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9224 HDA_AMP_MUTE, bits);
9225 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9226 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9227}
9228
9229static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9230 unsigned int res)
9231{
9232 if ((res >> 26) == ALC880_HP_EVENT)
9233 alc883_lenovo_101e_all_automute(codec);
9234 if ((res >> 26) == ALC880_FRONT_EVENT)
9235 alc883_lenovo_101e_ispeaker_automute(codec);
9236}
9237
676a9b53 9238/* toggle speaker-output according to the hp-jack state */
4f5d1706 9239static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9240{
a9fd4f3f 9241 struct alc_spec *spec = codec->spec;
676a9b53 9242
a9fd4f3f
TI
9243 spec->autocfg.hp_pins[0] = 0x14;
9244 spec->autocfg.speaker_pins[0] = 0x15;
9245 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9246}
9247
d1a991a6
KY
9248static struct hda_verb alc883_acer_eapd_verbs[] = {
9249 /* HP Pin: output 0 (0x0c) */
9250 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9252 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9253 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9254 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9255 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9256 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9257 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9258 /* eanable EAPD on medion laptop */
9259 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9260 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9261 /* enable unsolicited event */
9262 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9263 { }
9264};
9265
fc86f954
DK
9266static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9268 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9269 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9270 { } /* end */
9271};
9272
4f5d1706 9273static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9274{
a9fd4f3f 9275 struct alc_spec *spec = codec->spec;
5795b9e6 9276
a9fd4f3f
TI
9277 spec->autocfg.hp_pins[0] = 0x1b;
9278 spec->autocfg.speaker_pins[0] = 0x14;
9279 spec->autocfg.speaker_pins[1] = 0x15;
9280 spec->autocfg.speaker_pins[2] = 0x16;
9281 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9282}
9283
4f5d1706 9284static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9285{
a9fd4f3f 9286 struct alc_spec *spec = codec->spec;
e2757d5e 9287
a9fd4f3f
TI
9288 spec->autocfg.hp_pins[0] = 0x1b;
9289 spec->autocfg.speaker_pins[0] = 0x14;
9290 spec->autocfg.speaker_pins[1] = 0x15;
9291 spec->autocfg.speaker_pins[2] = 0x16;
9292 spec->autocfg.speaker_pins[3] = 0x17;
9293 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9294}
9295
4f5d1706 9296static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9297{
9298 struct alc_spec *spec = codec->spec;
9299
9300 spec->autocfg.hp_pins[0] = 0x15;
9301 spec->autocfg.speaker_pins[0] = 0x14;
9302 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9303}
9304
e2757d5e
KY
9305static struct hda_verb alc888_asus_m90v_verbs[] = {
9306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9309 /* enable unsolicited event */
9310 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9311 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9312 { } /* end */
9313};
9314
4f5d1706 9315static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9316{
a9fd4f3f 9317 struct alc_spec *spec = codec->spec;
e2757d5e 9318
a9fd4f3f
TI
9319 spec->autocfg.hp_pins[0] = 0x1b;
9320 spec->autocfg.speaker_pins[0] = 0x14;
9321 spec->autocfg.speaker_pins[1] = 0x15;
9322 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9323 spec->ext_mic.pin = 0x18;
9324 spec->int_mic.pin = 0x19;
9325 spec->ext_mic.mux_idx = 0;
9326 spec->int_mic.mux_idx = 1;
9327 spec->auto_mic = 1;
e2757d5e
KY
9328}
9329
9330static struct hda_verb alc888_asus_eee1601_verbs[] = {
9331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9332 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9333 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9336 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9337 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9338 /* enable unsolicited event */
9339 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9340 { } /* end */
9341};
9342
e2757d5e
KY
9343static void alc883_eee1601_inithook(struct hda_codec *codec)
9344{
a9fd4f3f
TI
9345 struct alc_spec *spec = codec->spec;
9346
9347 spec->autocfg.hp_pins[0] = 0x14;
9348 spec->autocfg.speaker_pins[0] = 0x1b;
9349 alc_automute_pin(codec);
e2757d5e
KY
9350}
9351
eb4c41d3
TS
9352static struct hda_verb alc889A_mb31_verbs[] = {
9353 /* Init rear pin (used as headphone output) */
9354 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9355 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9356 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9357 /* Init line pin (used as output in 4ch and 6ch mode) */
9358 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9359 /* Init line 2 pin (used as headphone out by default) */
9360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9361 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9362 { } /* end */
9363};
9364
9365/* Mute speakers according to the headphone jack state */
9366static void alc889A_mb31_automute(struct hda_codec *codec)
9367{
9368 unsigned int present;
9369
9370 /* Mute only in 2ch or 4ch mode */
9371 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9372 == 0x00) {
864f92be 9373 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9374 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9375 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9376 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9377 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9378 }
9379}
9380
9381static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9382{
9383 if ((res >> 26) == ALC880_HP_EVENT)
9384 alc889A_mb31_automute(codec);
9385}
9386
4953550a 9387
cb53c626 9388#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9389#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9390#endif
9391
def319f9 9392/* pcm configuration: identical with ALC880 */
4953550a
TI
9393#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9394#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9395#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9396#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9397
9398static hda_nid_t alc883_slave_dig_outs[] = {
9399 ALC1200_DIGOUT_NID, 0,
9400};
9401
9402static hda_nid_t alc1200_slave_dig_outs[] = {
9403 ALC883_DIGOUT_NID, 0,
9404};
9c7f852e
TI
9405
9406/*
9407 * configuration and preset
9408 */
4953550a
TI
9409static const char *alc882_models[ALC882_MODEL_LAST] = {
9410 [ALC882_3ST_DIG] = "3stack-dig",
9411 [ALC882_6ST_DIG] = "6stack-dig",
9412 [ALC882_ARIMA] = "arima",
9413 [ALC882_W2JC] = "w2jc",
9414 [ALC882_TARGA] = "targa",
9415 [ALC882_ASUS_A7J] = "asus-a7j",
9416 [ALC882_ASUS_A7M] = "asus-a7m",
9417 [ALC885_MACPRO] = "macpro",
9418 [ALC885_MB5] = "mb5",
e458b1fa 9419 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9420 [ALC885_MBA21] = "mba21",
4953550a
TI
9421 [ALC885_MBP3] = "mbp3",
9422 [ALC885_IMAC24] = "imac24",
4b7e1803 9423 [ALC885_IMAC91] = "imac91",
4953550a 9424 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9425 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9426 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9427 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9428 [ALC883_TARGA_DIG] = "targa-dig",
9429 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9430 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9431 [ALC883_ACER] = "acer",
2880a867 9432 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9433 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9434 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9435 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9436 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9437 [ALC883_MEDION] = "medion",
272a527c 9438 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9439 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9440 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9441 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9442 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9443 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9444 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9445 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9446 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9447 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9448 [ALC883_MITAC] = "mitac",
a65cc60f 9449 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9450 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9451 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9452 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9453 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9454 [ALC889A_INTEL] = "intel-alc889a",
9455 [ALC889_INTEL] = "intel-x58",
3ab90935 9456 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9457 [ALC889A_MB31] = "mb31",
3e1647c5 9458 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9459 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9460};
9461
4953550a
TI
9462static struct snd_pci_quirk alc882_cfg_tbl[] = {
9463 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9464
ac3e3741 9465 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9466 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9467 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9468 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9469 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9470 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9471 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9472 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9473 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9474 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9475 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9476 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9477 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9478 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9479 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9480 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9481 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9482 ALC888_ACER_ASPIRE_6530G),
cc374c47 9483 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9484 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9485 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9486 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9487 /* default Acer -- disabled as it causes more problems.
9488 * model=auto should work fine now
9489 */
9490 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9491
5795b9e6 9492 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9493
febe3375 9494 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9495 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9496 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9497 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9498 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9499 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9500
9501 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9502 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9503 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9504 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9505 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9506 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9507 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9508 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9509 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9510 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9511 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9512
9513 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9514 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9515 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9516 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9517 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9518 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9519 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9520 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9521 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9522
6f3bf657 9523 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9524 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9525 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9526 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9527 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9528 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9529 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9530 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9531 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9532 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9533 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9534 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9535 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9536 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9537 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9538 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9539 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9540 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9541 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9542 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9543 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9544 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9545 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9546 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9547 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9548 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9549 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9550 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9551 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9552 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9553 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9554
ac3e3741 9555 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9556 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9557 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9558 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9559 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9560 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9561 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9562 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9563 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9564 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9565 ALC883_FUJITSU_PI2515),
bfb53037 9566 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9567 ALC888_FUJITSU_XA3530),
272a527c 9568 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9569 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9570 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9571 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9572 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9573 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9574 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9575 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9576 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9577
17bba1b7
J
9578 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9579 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9580 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9581 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9582 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9583 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9584 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9585
4953550a 9586 {}
f3cd3f5d
WF
9587};
9588
4953550a
TI
9589/* codec SSID table for Intel Mac */
9590static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9591 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9592 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9593 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9594 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9595 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9596 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9597 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9598 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9599 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9600 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9601 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9602 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9603 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9604 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9605 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9606 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9607 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9608 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9609 * so apparently no perfect solution yet
4953550a
TI
9610 */
9611 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9612 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9613 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9614 {} /* terminator */
b25c9da1
WF
9615};
9616
4953550a
TI
9617static struct alc_config_preset alc882_presets[] = {
9618 [ALC882_3ST_DIG] = {
9619 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9620 .init_verbs = { alc882_base_init_verbs,
9621 alc882_adc1_init_verbs },
4953550a
TI
9622 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9623 .dac_nids = alc882_dac_nids,
9624 .dig_out_nid = ALC882_DIGOUT_NID,
9625 .dig_in_nid = ALC882_DIGIN_NID,
9626 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9627 .channel_mode = alc882_ch_modes,
9628 .need_dac_fix = 1,
9629 .input_mux = &alc882_capture_source,
9630 },
9631 [ALC882_6ST_DIG] = {
9632 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9633 .init_verbs = { alc882_base_init_verbs,
9634 alc882_adc1_init_verbs },
4953550a
TI
9635 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9636 .dac_nids = alc882_dac_nids,
9637 .dig_out_nid = ALC882_DIGOUT_NID,
9638 .dig_in_nid = ALC882_DIGIN_NID,
9639 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9640 .channel_mode = alc882_sixstack_modes,
9641 .input_mux = &alc882_capture_source,
9642 },
9643 [ALC882_ARIMA] = {
9644 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9645 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9646 alc882_eapd_verbs },
4953550a
TI
9647 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9648 .dac_nids = alc882_dac_nids,
9649 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9650 .channel_mode = alc882_sixstack_modes,
9651 .input_mux = &alc882_capture_source,
9652 },
9653 [ALC882_W2JC] = {
9654 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9655 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9656 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9657 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9658 .dac_nids = alc882_dac_nids,
9659 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9660 .channel_mode = alc880_threestack_modes,
9661 .need_dac_fix = 1,
9662 .input_mux = &alc882_capture_source,
9663 .dig_out_nid = ALC882_DIGOUT_NID,
9664 },
76e6f5a9
RH
9665 [ALC885_MBA21] = {
9666 .mixers = { alc885_mba21_mixer },
9667 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9668 .num_dacs = 2,
9669 .dac_nids = alc882_dac_nids,
9670 .channel_mode = alc885_mba21_ch_modes,
9671 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9672 .input_mux = &alc882_capture_source,
9673 .unsol_event = alc_automute_amp_unsol_event,
9674 .setup = alc885_mba21_setup,
9675 .init_hook = alc_automute_amp,
9676 },
4953550a
TI
9677 [ALC885_MBP3] = {
9678 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9679 .init_verbs = { alc885_mbp3_init_verbs,
9680 alc880_gpio1_init_verbs },
be0ae923 9681 .num_dacs = 2,
4953550a 9682 .dac_nids = alc882_dac_nids,
be0ae923
TI
9683 .hp_nid = 0x04,
9684 .channel_mode = alc885_mbp_4ch_modes,
9685 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9686 .input_mux = &alc882_capture_source,
9687 .dig_out_nid = ALC882_DIGOUT_NID,
9688 .dig_in_nid = ALC882_DIGIN_NID,
9689 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9690 .setup = alc885_mbp3_setup,
9691 .init_hook = alc_automute_amp,
4953550a
TI
9692 },
9693 [ALC885_MB5] = {
9694 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9695 .init_verbs = { alc885_mb5_init_verbs,
9696 alc880_gpio1_init_verbs },
9697 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9698 .dac_nids = alc882_dac_nids,
9699 .channel_mode = alc885_mb5_6ch_modes,
9700 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9701 .input_mux = &mb5_capture_source,
9702 .dig_out_nid = ALC882_DIGOUT_NID,
9703 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9704 .unsol_event = alc_automute_amp_unsol_event,
9705 .setup = alc885_mb5_setup,
9706 .init_hook = alc_automute_amp,
4953550a 9707 },
e458b1fa
LY
9708 [ALC885_MACMINI3] = {
9709 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9710 .init_verbs = { alc885_macmini3_init_verbs,
9711 alc880_gpio1_init_verbs },
9712 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9713 .dac_nids = alc882_dac_nids,
9714 .channel_mode = alc885_macmini3_6ch_modes,
9715 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9716 .input_mux = &macmini3_capture_source,
9717 .dig_out_nid = ALC882_DIGOUT_NID,
9718 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9719 .unsol_event = alc_automute_amp_unsol_event,
9720 .setup = alc885_macmini3_setup,
9721 .init_hook = alc_automute_amp,
e458b1fa 9722 },
4953550a
TI
9723 [ALC885_MACPRO] = {
9724 .mixers = { alc882_macpro_mixer },
9725 .init_verbs = { alc882_macpro_init_verbs },
9726 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9727 .dac_nids = alc882_dac_nids,
9728 .dig_out_nid = ALC882_DIGOUT_NID,
9729 .dig_in_nid = ALC882_DIGIN_NID,
9730 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9731 .channel_mode = alc882_ch_modes,
9732 .input_mux = &alc882_capture_source,
9733 .init_hook = alc885_macpro_init_hook,
9734 },
9735 [ALC885_IMAC24] = {
9736 .mixers = { alc885_imac24_mixer },
9737 .init_verbs = { alc885_imac24_init_verbs },
9738 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9739 .dac_nids = alc882_dac_nids,
9740 .dig_out_nid = ALC882_DIGOUT_NID,
9741 .dig_in_nid = ALC882_DIGIN_NID,
9742 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9743 .channel_mode = alc882_ch_modes,
9744 .input_mux = &alc882_capture_source,
9745 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9746 .setup = alc885_imac24_setup,
4953550a
TI
9747 .init_hook = alc885_imac24_init_hook,
9748 },
4b7e1803 9749 [ALC885_IMAC91] = {
b7cccc52 9750 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9751 .init_verbs = { alc885_imac91_init_verbs,
9752 alc880_gpio1_init_verbs },
9753 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9754 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9755 .channel_mode = alc885_mba21_ch_modes,
9756 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9757 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9758 .dig_out_nid = ALC882_DIGOUT_NID,
9759 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9760 .unsol_event = alc_automute_amp_unsol_event,
9761 .setup = alc885_imac91_setup,
9762 .init_hook = alc_automute_amp,
4b7e1803 9763 },
4953550a
TI
9764 [ALC882_TARGA] = {
9765 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9766 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9767 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9768 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9769 .dac_nids = alc882_dac_nids,
9770 .dig_out_nid = ALC882_DIGOUT_NID,
9771 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9772 .adc_nids = alc882_adc_nids,
9773 .capsrc_nids = alc882_capsrc_nids,
9774 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9775 .channel_mode = alc882_3ST_6ch_modes,
9776 .need_dac_fix = 1,
9777 .input_mux = &alc882_capture_source,
9778 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9779 .setup = alc882_targa_setup,
9780 .init_hook = alc882_targa_automute,
4953550a
TI
9781 },
9782 [ALC882_ASUS_A7J] = {
9783 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9784 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9785 alc882_asus_a7j_verbs},
4953550a
TI
9786 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9787 .dac_nids = alc882_dac_nids,
9788 .dig_out_nid = ALC882_DIGOUT_NID,
9789 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9790 .adc_nids = alc882_adc_nids,
9791 .capsrc_nids = alc882_capsrc_nids,
9792 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9793 .channel_mode = alc882_3ST_6ch_modes,
9794 .need_dac_fix = 1,
9795 .input_mux = &alc882_capture_source,
9796 },
9797 [ALC882_ASUS_A7M] = {
9798 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9799 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9800 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9801 alc882_asus_a7m_verbs },
9802 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9803 .dac_nids = alc882_dac_nids,
9804 .dig_out_nid = ALC882_DIGOUT_NID,
9805 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9806 .channel_mode = alc880_threestack_modes,
9807 .need_dac_fix = 1,
9808 .input_mux = &alc882_capture_source,
9809 },
9c7f852e
TI
9810 [ALC883_3ST_2ch_DIG] = {
9811 .mixers = { alc883_3ST_2ch_mixer },
9812 .init_verbs = { alc883_init_verbs },
9813 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9814 .dac_nids = alc883_dac_nids,
9815 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9816 .dig_in_nid = ALC883_DIGIN_NID,
9817 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9818 .channel_mode = alc883_3ST_2ch_modes,
9819 .input_mux = &alc883_capture_source,
9820 },
9821 [ALC883_3ST_6ch_DIG] = {
9822 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9823 .init_verbs = { alc883_init_verbs },
9824 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9825 .dac_nids = alc883_dac_nids,
9826 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9827 .dig_in_nid = ALC883_DIGIN_NID,
9828 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9829 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9830 .need_dac_fix = 1,
9c7f852e 9831 .input_mux = &alc883_capture_source,
f12ab1e0 9832 },
9c7f852e
TI
9833 [ALC883_3ST_6ch] = {
9834 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9835 .init_verbs = { alc883_init_verbs },
9836 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9837 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9838 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9839 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9840 .need_dac_fix = 1,
9c7f852e 9841 .input_mux = &alc883_capture_source,
f12ab1e0 9842 },
17bba1b7
J
9843 [ALC883_3ST_6ch_INTEL] = {
9844 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9845 .init_verbs = { alc883_init_verbs },
9846 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9847 .dac_nids = alc883_dac_nids,
9848 .dig_out_nid = ALC883_DIGOUT_NID,
9849 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9850 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9851 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9852 .channel_mode = alc883_3ST_6ch_intel_modes,
9853 .need_dac_fix = 1,
9854 .input_mux = &alc883_3stack_6ch_intel,
9855 },
87a8c370
JK
9856 [ALC889A_INTEL] = {
9857 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9858 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9859 alc_hp15_unsol_verbs },
87a8c370
JK
9860 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9861 .dac_nids = alc883_dac_nids,
9862 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9863 .adc_nids = alc889_adc_nids,
9864 .dig_out_nid = ALC883_DIGOUT_NID,
9865 .dig_in_nid = ALC883_DIGIN_NID,
9866 .slave_dig_outs = alc883_slave_dig_outs,
9867 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9868 .channel_mode = alc889_8ch_intel_modes,
9869 .capsrc_nids = alc889_capsrc_nids,
9870 .input_mux = &alc889_capture_source,
4f5d1706
TI
9871 .setup = alc889_automute_setup,
9872 .init_hook = alc_automute_amp,
6732bd0d 9873 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9874 .need_dac_fix = 1,
9875 },
9876 [ALC889_INTEL] = {
9877 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9878 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9879 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9880 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9881 .dac_nids = alc883_dac_nids,
9882 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9883 .adc_nids = alc889_adc_nids,
9884 .dig_out_nid = ALC883_DIGOUT_NID,
9885 .dig_in_nid = ALC883_DIGIN_NID,
9886 .slave_dig_outs = alc883_slave_dig_outs,
9887 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9888 .channel_mode = alc889_8ch_intel_modes,
9889 .capsrc_nids = alc889_capsrc_nids,
9890 .input_mux = &alc889_capture_source,
4f5d1706 9891 .setup = alc889_automute_setup,
6732bd0d
WF
9892 .init_hook = alc889_intel_init_hook,
9893 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9894 .need_dac_fix = 1,
9895 },
9c7f852e
TI
9896 [ALC883_6ST_DIG] = {
9897 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9898 .init_verbs = { alc883_init_verbs },
9899 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9900 .dac_nids = alc883_dac_nids,
9901 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9902 .dig_in_nid = ALC883_DIGIN_NID,
9903 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9904 .channel_mode = alc883_sixstack_modes,
9905 .input_mux = &alc883_capture_source,
9906 },
ccc656ce 9907 [ALC883_TARGA_DIG] = {
c259249f 9908 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9909 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9910 alc883_targa_verbs},
ccc656ce
KY
9911 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9912 .dac_nids = alc883_dac_nids,
9913 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9914 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9915 .channel_mode = alc883_3ST_6ch_modes,
9916 .need_dac_fix = 1,
9917 .input_mux = &alc883_capture_source,
c259249f 9918 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9919 .setup = alc882_targa_setup,
9920 .init_hook = alc882_targa_automute,
ccc656ce
KY
9921 },
9922 [ALC883_TARGA_2ch_DIG] = {
c259249f 9923 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9924 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9925 alc883_targa_verbs},
ccc656ce
KY
9926 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9927 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9928 .adc_nids = alc883_adc_nids_alt,
9929 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9930 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9931 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9932 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9933 .channel_mode = alc883_3ST_2ch_modes,
9934 .input_mux = &alc883_capture_source,
c259249f 9935 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9936 .setup = alc882_targa_setup,
9937 .init_hook = alc882_targa_automute,
ccc656ce 9938 },
64a8be74 9939 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9940 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9941 alc883_chmode_mixer },
64a8be74 9942 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9943 alc883_targa_verbs },
64a8be74
DH
9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9945 .dac_nids = alc883_dac_nids,
9946 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9947 .adc_nids = alc883_adc_nids_rev,
9948 .capsrc_nids = alc883_capsrc_nids_rev,
9949 .dig_out_nid = ALC883_DIGOUT_NID,
9950 .dig_in_nid = ALC883_DIGIN_NID,
9951 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9952 .channel_mode = alc883_4ST_8ch_modes,
9953 .need_dac_fix = 1,
9954 .input_mux = &alc883_capture_source,
c259249f 9955 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9956 .setup = alc882_targa_setup,
9957 .init_hook = alc882_targa_automute,
64a8be74 9958 },
bab282b9 9959 [ALC883_ACER] = {
676a9b53 9960 .mixers = { alc883_base_mixer },
bab282b9
VA
9961 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9962 * and the headphone jack. Turn this on and rely on the
9963 * standard mute methods whenever the user wants to turn
9964 * these outputs off.
9965 */
9966 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9967 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9968 .dac_nids = alc883_dac_nids,
bab282b9
VA
9969 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9970 .channel_mode = alc883_3ST_2ch_modes,
9971 .input_mux = &alc883_capture_source,
9972 },
2880a867 9973 [ALC883_ACER_ASPIRE] = {
676a9b53 9974 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 9975 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
9976 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9977 .dac_nids = alc883_dac_nids,
9978 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
9979 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9980 .channel_mode = alc883_3ST_2ch_modes,
9981 .input_mux = &alc883_capture_source,
a9fd4f3f 9982 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9983 .setup = alc883_acer_aspire_setup,
9984 .init_hook = alc_automute_amp,
d1a991a6 9985 },
5b2d1eca 9986 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 9987 .mixers = { alc888_base_mixer,
5b2d1eca
VP
9988 alc883_chmode_mixer },
9989 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9990 alc888_acer_aspire_4930g_verbs },
9991 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9992 .dac_nids = alc883_dac_nids,
9993 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9994 .adc_nids = alc883_adc_nids_rev,
9995 .capsrc_nids = alc883_capsrc_nids_rev,
9996 .dig_out_nid = ALC883_DIGOUT_NID,
9997 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9998 .channel_mode = alc883_3ST_6ch_modes,
9999 .need_dac_fix = 1,
973b8cb0 10000 .const_channel_count = 6,
5b2d1eca 10001 .num_mux_defs =
ef8ef5fb
VP
10002 ARRAY_SIZE(alc888_2_capture_sources),
10003 .input_mux = alc888_2_capture_sources,
d2fd4b09 10004 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10005 .setup = alc888_acer_aspire_4930g_setup,
10006 .init_hook = alc_automute_amp,
d2fd4b09
TV
10007 },
10008 [ALC888_ACER_ASPIRE_6530G] = {
10009 .mixers = { alc888_acer_aspire_6530_mixer },
10010 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10011 alc888_acer_aspire_6530g_verbs },
10012 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10013 .dac_nids = alc883_dac_nids,
10014 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10015 .adc_nids = alc883_adc_nids_rev,
10016 .capsrc_nids = alc883_capsrc_nids_rev,
10017 .dig_out_nid = ALC883_DIGOUT_NID,
10018 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10019 .channel_mode = alc883_3ST_2ch_modes,
10020 .num_mux_defs =
10021 ARRAY_SIZE(alc888_2_capture_sources),
10022 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10023 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10024 .setup = alc888_acer_aspire_6530g_setup,
10025 .init_hook = alc_automute_amp,
5b2d1eca 10026 },
3b315d70 10027 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10028 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10029 alc883_chmode_mixer },
10030 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10031 alc889_acer_aspire_8930g_verbs,
10032 alc889_eapd_verbs},
3b315d70
HM
10033 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10034 .dac_nids = alc883_dac_nids,
018df418
HM
10035 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10036 .adc_nids = alc889_adc_nids,
10037 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10038 .dig_out_nid = ALC883_DIGOUT_NID,
10039 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10040 .channel_mode = alc883_3ST_6ch_modes,
10041 .need_dac_fix = 1,
10042 .const_channel_count = 6,
10043 .num_mux_defs =
018df418
HM
10044 ARRAY_SIZE(alc889_capture_sources),
10045 .input_mux = alc889_capture_sources,
3b315d70 10046 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10047 .setup = alc889_acer_aspire_8930g_setup,
10048 .init_hook = alc_automute_amp,
f5de24b0 10049#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10050 .power_hook = alc_power_eapd,
f5de24b0 10051#endif
3b315d70 10052 },
fc86f954
DK
10053 [ALC888_ACER_ASPIRE_7730G] = {
10054 .mixers = { alc883_3ST_6ch_mixer,
10055 alc883_chmode_mixer },
10056 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10057 alc888_acer_aspire_7730G_verbs },
10058 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10059 .dac_nids = alc883_dac_nids,
10060 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10061 .adc_nids = alc883_adc_nids_rev,
10062 .capsrc_nids = alc883_capsrc_nids_rev,
10063 .dig_out_nid = ALC883_DIGOUT_NID,
10064 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10065 .channel_mode = alc883_3ST_6ch_modes,
10066 .need_dac_fix = 1,
10067 .const_channel_count = 6,
10068 .input_mux = &alc883_capture_source,
10069 .unsol_event = alc_automute_amp_unsol_event,
10070 .setup = alc888_acer_aspire_6530g_setup,
10071 .init_hook = alc_automute_amp,
10072 },
c07584c8
TD
10073 [ALC883_MEDION] = {
10074 .mixers = { alc883_fivestack_mixer,
10075 alc883_chmode_mixer },
10076 .init_verbs = { alc883_init_verbs,
b373bdeb 10077 alc883_medion_eapd_verbs },
c07584c8
TD
10078 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10079 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10080 .adc_nids = alc883_adc_nids_alt,
10081 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10082 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10083 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10084 .channel_mode = alc883_sixstack_modes,
10085 .input_mux = &alc883_capture_source,
b373bdeb 10086 },
272a527c
KY
10087 [ALC883_MEDION_MD2] = {
10088 .mixers = { alc883_medion_md2_mixer},
10089 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10090 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10091 .dac_nids = alc883_dac_nids,
10092 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10093 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10094 .channel_mode = alc883_3ST_2ch_modes,
10095 .input_mux = &alc883_capture_source,
a9fd4f3f 10096 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10097 .setup = alc883_medion_md2_setup,
10098 .init_hook = alc_automute_amp,
ea1fb29a 10099 },
7ad7b218
MC
10100 [ALC883_MEDION_WIM2160] = {
10101 .mixers = { alc883_medion_wim2160_mixer },
10102 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10103 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10104 .dac_nids = alc883_dac_nids,
10105 .dig_out_nid = ALC883_DIGOUT_NID,
10106 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10107 .adc_nids = alc883_adc_nids,
10108 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10109 .channel_mode = alc883_3ST_2ch_modes,
10110 .input_mux = &alc883_capture_source,
10111 .unsol_event = alc_automute_amp_unsol_event,
10112 .setup = alc883_medion_wim2160_setup,
10113 .init_hook = alc_automute_amp,
10114 },
b373bdeb 10115 [ALC883_LAPTOP_EAPD] = {
676a9b53 10116 .mixers = { alc883_base_mixer },
b373bdeb
AN
10117 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10118 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10119 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10120 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10121 .channel_mode = alc883_3ST_2ch_modes,
10122 .input_mux = &alc883_capture_source,
10123 },
a65cc60f 10124 [ALC883_CLEVO_M540R] = {
10125 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10126 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10127 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10128 .dac_nids = alc883_dac_nids,
10129 .dig_out_nid = ALC883_DIGOUT_NID,
10130 .dig_in_nid = ALC883_DIGIN_NID,
10131 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10132 .channel_mode = alc883_3ST_6ch_clevo_modes,
10133 .need_dac_fix = 1,
10134 .input_mux = &alc883_capture_source,
10135 /* This machine has the hardware HP auto-muting, thus
10136 * we need no software mute via unsol event
10137 */
10138 },
0c4cc443
HRK
10139 [ALC883_CLEVO_M720] = {
10140 .mixers = { alc883_clevo_m720_mixer },
10141 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10142 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10143 .dac_nids = alc883_dac_nids,
10144 .dig_out_nid = ALC883_DIGOUT_NID,
10145 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10146 .channel_mode = alc883_3ST_2ch_modes,
10147 .input_mux = &alc883_capture_source,
0c4cc443 10148 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10149 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10150 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10151 },
bc9f98a9
KY
10152 [ALC883_LENOVO_101E_2ch] = {
10153 .mixers = { alc883_lenovo_101e_2ch_mixer},
10154 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10155 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10156 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10157 .adc_nids = alc883_adc_nids_alt,
10158 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10159 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10160 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10161 .channel_mode = alc883_3ST_2ch_modes,
10162 .input_mux = &alc883_lenovo_101e_capture_source,
10163 .unsol_event = alc883_lenovo_101e_unsol_event,
10164 .init_hook = alc883_lenovo_101e_all_automute,
10165 },
272a527c
KY
10166 [ALC883_LENOVO_NB0763] = {
10167 .mixers = { alc883_lenovo_nb0763_mixer },
10168 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10169 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10170 .dac_nids = alc883_dac_nids,
272a527c
KY
10171 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10172 .channel_mode = alc883_3ST_2ch_modes,
10173 .need_dac_fix = 1,
10174 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10175 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10176 .setup = alc883_medion_md2_setup,
10177 .init_hook = alc_automute_amp,
272a527c
KY
10178 },
10179 [ALC888_LENOVO_MS7195_DIG] = {
10180 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10181 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10182 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10183 .dac_nids = alc883_dac_nids,
10184 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10185 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10186 .channel_mode = alc883_3ST_6ch_modes,
10187 .need_dac_fix = 1,
10188 .input_mux = &alc883_capture_source,
10189 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10190 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10191 },
10192 [ALC883_HAIER_W66] = {
c259249f 10193 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10194 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10195 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10196 .dac_nids = alc883_dac_nids,
10197 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10198 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10199 .channel_mode = alc883_3ST_2ch_modes,
10200 .input_mux = &alc883_capture_source,
a9fd4f3f 10201 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10202 .setup = alc883_haier_w66_setup,
10203 .init_hook = alc_automute_amp,
eea6419e 10204 },
4723c022 10205 [ALC888_3ST_HP] = {
eea6419e 10206 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10207 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10208 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10209 .dac_nids = alc883_dac_nids,
4723c022
CM
10210 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10211 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10212 .need_dac_fix = 1,
10213 .input_mux = &alc883_capture_source,
a9fd4f3f 10214 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10215 .setup = alc888_3st_hp_setup,
10216 .init_hook = alc_automute_amp,
8341de60 10217 },
5795b9e6 10218 [ALC888_6ST_DELL] = {
f24dbdc6 10219 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10220 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10221 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10222 .dac_nids = alc883_dac_nids,
10223 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10224 .dig_in_nid = ALC883_DIGIN_NID,
10225 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10226 .channel_mode = alc883_sixstack_modes,
10227 .input_mux = &alc883_capture_source,
a9fd4f3f 10228 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10229 .setup = alc888_6st_dell_setup,
10230 .init_hook = alc_automute_amp,
5795b9e6 10231 },
a8848bd6
AS
10232 [ALC883_MITAC] = {
10233 .mixers = { alc883_mitac_mixer },
10234 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10235 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10236 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10237 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10238 .channel_mode = alc883_3ST_2ch_modes,
10239 .input_mux = &alc883_capture_source,
a9fd4f3f 10240 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10241 .setup = alc883_mitac_setup,
10242 .init_hook = alc_automute_amp,
a8848bd6 10243 },
fb97dc67
J
10244 [ALC883_FUJITSU_PI2515] = {
10245 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10246 .init_verbs = { alc883_init_verbs,
10247 alc883_2ch_fujitsu_pi2515_verbs},
10248 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10249 .dac_nids = alc883_dac_nids,
10250 .dig_out_nid = ALC883_DIGOUT_NID,
10251 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10252 .channel_mode = alc883_3ST_2ch_modes,
10253 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10254 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10255 .setup = alc883_2ch_fujitsu_pi2515_setup,
10256 .init_hook = alc_automute_amp,
fb97dc67 10257 },
ef8ef5fb
VP
10258 [ALC888_FUJITSU_XA3530] = {
10259 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10260 .init_verbs = { alc883_init_verbs,
10261 alc888_fujitsu_xa3530_verbs },
10262 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10263 .dac_nids = alc883_dac_nids,
10264 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10265 .adc_nids = alc883_adc_nids_rev,
10266 .capsrc_nids = alc883_capsrc_nids_rev,
10267 .dig_out_nid = ALC883_DIGOUT_NID,
10268 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10269 .channel_mode = alc888_4ST_8ch_intel_modes,
10270 .num_mux_defs =
10271 ARRAY_SIZE(alc888_2_capture_sources),
10272 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10273 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10274 .setup = alc888_fujitsu_xa3530_setup,
10275 .init_hook = alc_automute_amp,
ef8ef5fb 10276 },
e2757d5e
KY
10277 [ALC888_LENOVO_SKY] = {
10278 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10279 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10281 .dac_nids = alc883_dac_nids,
10282 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10283 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10284 .channel_mode = alc883_sixstack_modes,
10285 .need_dac_fix = 1,
10286 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10287 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10288 .setup = alc888_lenovo_sky_setup,
10289 .init_hook = alc_automute_amp,
e2757d5e
KY
10290 },
10291 [ALC888_ASUS_M90V] = {
10292 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10293 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10294 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10295 .dac_nids = alc883_dac_nids,
10296 .dig_out_nid = ALC883_DIGOUT_NID,
10297 .dig_in_nid = ALC883_DIGIN_NID,
10298 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10299 .channel_mode = alc883_3ST_6ch_modes,
10300 .need_dac_fix = 1,
10301 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10302 .unsol_event = alc_sku_unsol_event,
10303 .setup = alc883_mode2_setup,
10304 .init_hook = alc_inithook,
e2757d5e
KY
10305 },
10306 [ALC888_ASUS_EEE1601] = {
10307 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10308 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10309 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10310 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10311 .dac_nids = alc883_dac_nids,
10312 .dig_out_nid = ALC883_DIGOUT_NID,
10313 .dig_in_nid = ALC883_DIGIN_NID,
10314 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10315 .channel_mode = alc883_3ST_2ch_modes,
10316 .need_dac_fix = 1,
10317 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10318 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10319 .init_hook = alc883_eee1601_inithook,
10320 },
3ab90935
WF
10321 [ALC1200_ASUS_P5Q] = {
10322 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10323 .init_verbs = { alc883_init_verbs },
10324 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10325 .dac_nids = alc883_dac_nids,
10326 .dig_out_nid = ALC1200_DIGOUT_NID,
10327 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10328 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10329 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10330 .channel_mode = alc883_sixstack_modes,
10331 .input_mux = &alc883_capture_source,
10332 },
eb4c41d3
TS
10333 [ALC889A_MB31] = {
10334 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10335 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10336 alc880_gpio1_init_verbs },
10337 .adc_nids = alc883_adc_nids,
10338 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10339 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10340 .dac_nids = alc883_dac_nids,
10341 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10342 .channel_mode = alc889A_mb31_6ch_modes,
10343 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10344 .input_mux = &alc889A_mb31_capture_source,
10345 .dig_out_nid = ALC883_DIGOUT_NID,
10346 .unsol_event = alc889A_mb31_unsol_event,
10347 .init_hook = alc889A_mb31_automute,
10348 },
3e1647c5
GG
10349 [ALC883_SONY_VAIO_TT] = {
10350 .mixers = { alc883_vaiott_mixer },
10351 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10352 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10353 .dac_nids = alc883_dac_nids,
10354 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10355 .channel_mode = alc883_3ST_2ch_modes,
10356 .input_mux = &alc883_capture_source,
10357 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10358 .setup = alc883_vaiott_setup,
10359 .init_hook = alc_automute_amp,
3e1647c5 10360 },
9c7f852e
TI
10361};
10362
10363
4953550a
TI
10364/*
10365 * Pin config fixes
10366 */
10367enum {
10368 PINFIX_ABIT_AW9D_MAX
10369};
10370
10371static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10372 { 0x15, 0x01080104 }, /* side */
10373 { 0x16, 0x01011012 }, /* rear */
10374 { 0x17, 0x01016011 }, /* clfe */
10375 { }
10376};
10377
f8f25ba3
TI
10378static const struct alc_fixup alc882_fixups[] = {
10379 [PINFIX_ABIT_AW9D_MAX] = {
10380 .pins = alc882_abit_aw9d_pinfix
10381 },
4953550a
TI
10382};
10383
f8f25ba3 10384static struct snd_pci_quirk alc882_fixup_tbl[] = {
4953550a
TI
10385 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10386 {}
10387};
10388
9c7f852e
TI
10389/*
10390 * BIOS auto configuration
10391 */
05f5f477
TI
10392static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10393 const struct auto_pin_cfg *cfg)
10394{
10395 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10396}
10397
4953550a 10398static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10399 hda_nid_t nid, int pin_type,
489008cd 10400 hda_nid_t dac)
9c7f852e 10401{
f12ab1e0
TI
10402 int idx;
10403
489008cd 10404 /* set as output */
f6c7e546 10405 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10406
10407 if (dac == 0x25)
9c7f852e 10408 idx = 4;
489008cd
TI
10409 else if (dac >= 0x02 && dac <= 0x05)
10410 idx = dac - 2;
f9700d5a 10411 else
489008cd 10412 return;
9c7f852e 10413 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10414}
10415
4953550a 10416static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10417{
10418 struct alc_spec *spec = codec->spec;
10419 int i;
10420
10421 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10422 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10423 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10424 if (nid)
4953550a 10425 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10426 spec->multiout.dac_nids[i]);
9c7f852e
TI
10427 }
10428}
10429
4953550a 10430static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10431{
10432 struct alc_spec *spec = codec->spec;
489008cd 10433 hda_nid_t pin, dac;
9c7f852e 10434
eb06ed8f 10435 pin = spec->autocfg.hp_pins[0];
489008cd
TI
10436 if (pin) {
10437 dac = spec->multiout.hp_nid;
10438 if (!dac)
10439 dac = spec->multiout.dac_nids[0]; /* to front */
10440 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10441 }
f6c7e546 10442 pin = spec->autocfg.speaker_pins[0];
489008cd
TI
10443 if (pin) {
10444 dac = spec->multiout.extra_out_nid[0];
10445 if (!dac)
10446 dac = spec->multiout.dac_nids[0]; /* to front */
10447 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10448 }
9c7f852e
TI
10449}
10450
4953550a 10451static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10452{
10453 struct alc_spec *spec = codec->spec;
10454 int i;
10455
10456 for (i = 0; i < AUTO_PIN_LAST; i++) {
10457 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10458 if (!nid)
10459 continue;
0d971c9f 10460 alc_set_input_pin(codec, nid, i);
4953550a
TI
10461 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10462 snd_hda_codec_write(codec, nid, 0,
10463 AC_VERB_SET_AMP_GAIN_MUTE,
10464 AMP_OUT_MUTE);
10465 }
10466}
10467
10468static void alc882_auto_init_input_src(struct hda_codec *codec)
10469{
10470 struct alc_spec *spec = codec->spec;
10471 int c;
10472
10473 for (c = 0; c < spec->num_adc_nids; c++) {
10474 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10475 hda_nid_t nid = spec->capsrc_nids[c];
10476 unsigned int mux_idx;
10477 const struct hda_input_mux *imux;
10478 int conns, mute, idx, item;
10479
10480 conns = snd_hda_get_connections(codec, nid, conn_list,
10481 ARRAY_SIZE(conn_list));
10482 if (conns < 0)
10483 continue;
10484 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10485 imux = &spec->input_mux[mux_idx];
5311114d
TI
10486 if (!imux->num_items && mux_idx > 0)
10487 imux = &spec->input_mux[0];
4953550a
TI
10488 for (idx = 0; idx < conns; idx++) {
10489 /* if the current connection is the selected one,
10490 * unmute it as default - otherwise mute it
10491 */
10492 mute = AMP_IN_MUTE(idx);
10493 for (item = 0; item < imux->num_items; item++) {
10494 if (imux->items[item].index == idx) {
10495 if (spec->cur_mux[c] == item)
10496 mute = AMP_IN_UNMUTE(idx);
10497 break;
10498 }
10499 }
10500 /* check if we have a selector or mixer
10501 * we could check for the widget type instead, but
10502 * just check for Amp-In presence (in case of mixer
10503 * without amp-in there is something wrong, this
10504 * function shouldn't be used or capsrc nid is wrong)
10505 */
10506 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10507 snd_hda_codec_write(codec, nid, 0,
10508 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10509 mute);
10510 else if (mute != AMP_IN_MUTE(idx))
10511 snd_hda_codec_write(codec, nid, 0,
10512 AC_VERB_SET_CONNECT_SEL,
10513 idx);
9c7f852e
TI
10514 }
10515 }
10516}
10517
4953550a
TI
10518/* add mic boosts if needed */
10519static int alc_auto_add_mic_boost(struct hda_codec *codec)
10520{
10521 struct alc_spec *spec = codec->spec;
10522 int err;
10523 hda_nid_t nid;
10524
10525 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10526 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10527 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10528 "Mic Boost",
10529 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10530 if (err < 0)
10531 return err;
10532 }
10533 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10534 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10535 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10536 "Front Mic Boost",
10537 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10538 if (err < 0)
10539 return err;
10540 }
10541 return 0;
10542}
f511b01c 10543
9c7f852e 10544/* almost identical with ALC880 parser... */
4953550a 10545static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10546{
10547 struct alc_spec *spec = codec->spec;
05f5f477
TI
10548 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10549 int i, err;
9c7f852e 10550
05f5f477
TI
10551 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10552 alc882_ignore);
9c7f852e
TI
10553 if (err < 0)
10554 return err;
05f5f477
TI
10555 if (!spec->autocfg.line_outs)
10556 return 0; /* can't find valid BIOS pin config */
776e184e 10557
05f5f477
TI
10558 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10559 if (err < 0)
10560 return err;
10561 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10562 if (err < 0)
10563 return err;
10564 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10565 "Headphone");
05f5f477
TI
10566 if (err < 0)
10567 return err;
10568 err = alc880_auto_create_extra_out(spec,
10569 spec->autocfg.speaker_pins[0],
10570 "Speaker");
10571 if (err < 0)
10572 return err;
05f5f477 10573 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10574 if (err < 0)
10575 return err;
10576
05f5f477
TI
10577 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10578
10579 /* check multiple SPDIF-out (for recent codecs) */
10580 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10581 hda_nid_t dig_nid;
10582 err = snd_hda_get_connections(codec,
10583 spec->autocfg.dig_out_pins[i],
10584 &dig_nid, 1);
10585 if (err < 0)
10586 continue;
10587 if (!i)
10588 spec->multiout.dig_out_nid = dig_nid;
10589 else {
10590 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
71121d9f 10591 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
05f5f477 10592 break;
71121d9f 10593 spec->slave_dig_outs[i - 1] = dig_nid;
05f5f477
TI
10594 }
10595 }
10596 if (spec->autocfg.dig_in_pin)
10597 spec->dig_in_nid = ALC880_DIGIN_NID;
10598
10599 if (spec->kctls.list)
10600 add_mixer(spec, spec->kctls.list);
10601
10602 add_verb(spec, alc883_auto_init_verbs);
4953550a 10603 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10604 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10605 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10606
05f5f477
TI
10607 spec->num_mux_defs = 1;
10608 spec->input_mux = &spec->private_imux[0];
10609
6227cdce 10610 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10611
10612 err = alc_auto_add_mic_boost(codec);
10613 if (err < 0)
10614 return err;
61b9b9b1 10615
776e184e 10616 return 1; /* config found */
9c7f852e
TI
10617}
10618
10619/* additional initialization for auto-configuration model */
4953550a 10620static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10621{
f6c7e546 10622 struct alc_spec *spec = codec->spec;
4953550a
TI
10623 alc882_auto_init_multi_out(codec);
10624 alc882_auto_init_hp_out(codec);
10625 alc882_auto_init_analog_input(codec);
10626 alc882_auto_init_input_src(codec);
f6c7e546 10627 if (spec->unsol_event)
7fb0d78f 10628 alc_inithook(codec);
9c7f852e
TI
10629}
10630
4953550a 10631static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10632{
10633 struct alc_spec *spec;
10634 int err, board_config;
10635
10636 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10637 if (spec == NULL)
10638 return -ENOMEM;
10639
10640 codec->spec = spec;
10641
da00c244
KY
10642 alc_auto_parse_customize_define(codec);
10643
4953550a
TI
10644 switch (codec->vendor_id) {
10645 case 0x10ec0882:
10646 case 0x10ec0885:
10647 break;
10648 default:
10649 /* ALC883 and variants */
10650 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10651 break;
10652 }
2c3bf9ab 10653
4953550a
TI
10654 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10655 alc882_models,
10656 alc882_cfg_tbl);
10657
10658 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10659 board_config = snd_hda_check_board_codec_sid_config(codec,
10660 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10661
10662 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10663 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10664 codec->chip_name);
10665 board_config = ALC882_AUTO;
9c7f852e
TI
10666 }
10667
7fa90e87
TI
10668 if (board_config == ALC882_AUTO)
10669 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10670
10671 if (board_config == ALC882_AUTO) {
9c7f852e 10672 /* automatic parse from the BIOS config */
4953550a 10673 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10674 if (err < 0) {
10675 alc_free(codec);
10676 return err;
f12ab1e0 10677 } else if (!err) {
9c7f852e
TI
10678 printk(KERN_INFO
10679 "hda_codec: Cannot set up configuration "
10680 "from BIOS. Using base mode...\n");
4953550a 10681 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10682 }
10683 }
10684
dc1eae25 10685 if (has_cdefine_beep(codec)) {
8af2591d
TI
10686 err = snd_hda_attach_beep_device(codec, 0x1);
10687 if (err < 0) {
10688 alc_free(codec);
10689 return err;
10690 }
680cd536
KK
10691 }
10692
4953550a 10693 if (board_config != ALC882_AUTO)
e9c364c0 10694 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10695
4953550a
TI
10696 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10697 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10698 /* FIXME: setup DAC5 */
10699 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10700 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10701
10702 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10703 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10704
4953550a 10705 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10706 int i, j;
4953550a
TI
10707 spec->num_adc_nids = 0;
10708 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10709 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10710 hda_nid_t cap;
d11f74c6 10711 hda_nid_t items[16];
4953550a
TI
10712 hda_nid_t nid = alc882_adc_nids[i];
10713 unsigned int wcap = get_wcaps(codec, nid);
10714 /* get type */
a22d543a 10715 wcap = get_wcaps_type(wcap);
4953550a
TI
10716 if (wcap != AC_WID_AUD_IN)
10717 continue;
10718 spec->private_adc_nids[spec->num_adc_nids] = nid;
10719 err = snd_hda_get_connections(codec, nid, &cap, 1);
10720 if (err < 0)
10721 continue;
d11f74c6
TI
10722 err = snd_hda_get_connections(codec, cap, items,
10723 ARRAY_SIZE(items));
10724 if (err < 0)
10725 continue;
10726 for (j = 0; j < imux->num_items; j++)
10727 if (imux->items[j].index >= err)
10728 break;
10729 if (j < imux->num_items)
10730 continue;
4953550a
TI
10731 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10732 spec->num_adc_nids++;
61b9b9b1 10733 }
4953550a
TI
10734 spec->adc_nids = spec->private_adc_nids;
10735 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10736 }
10737
b59bdf3b 10738 set_capture_mixer(codec);
da00c244 10739
dc1eae25 10740 if (has_cdefine_beep(codec))
da00c244 10741 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10742
7fa90e87
TI
10743 if (board_config == ALC882_AUTO)
10744 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10745
2134ea4f
TI
10746 spec->vmaster_nid = 0x0c;
10747
9c7f852e 10748 codec->patch_ops = alc_patch_ops;
4953550a
TI
10749 if (board_config == ALC882_AUTO)
10750 spec->init_hook = alc882_auto_init;
cb53c626
TI
10751#ifdef CONFIG_SND_HDA_POWER_SAVE
10752 if (!spec->loopback.amplist)
4953550a 10753 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10754#endif
9c7f852e
TI
10755
10756 return 0;
10757}
10758
4953550a 10759
9c7f852e
TI
10760/*
10761 * ALC262 support
10762 */
10763
10764#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10765#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10766
10767#define alc262_dac_nids alc260_dac_nids
10768#define alc262_adc_nids alc882_adc_nids
10769#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10770#define alc262_capsrc_nids alc882_capsrc_nids
10771#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10772
10773#define alc262_modes alc260_modes
10774#define alc262_capture_source alc882_capture_source
10775
4e555fe5
KY
10776static hda_nid_t alc262_dmic_adc_nids[1] = {
10777 /* ADC0 */
10778 0x09
10779};
10780
10781static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10782
9c7f852e
TI
10783static struct snd_kcontrol_new alc262_base_mixer[] = {
10784 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10785 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10786 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10787 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10788 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10789 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10792 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10793 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10794 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10795 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10796 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10797 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10798 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10799 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10800 { } /* end */
10801};
10802
ce875f07
TI
10803/* update HP, line and mono-out pins according to the master switch */
10804static void alc262_hp_master_update(struct hda_codec *codec)
10805{
10806 struct alc_spec *spec = codec->spec;
10807 int val = spec->master_sw;
10808
10809 /* HP & line-out */
10810 snd_hda_codec_write_cache(codec, 0x1b, 0,
10811 AC_VERB_SET_PIN_WIDGET_CONTROL,
10812 val ? PIN_HP : 0);
10813 snd_hda_codec_write_cache(codec, 0x15, 0,
10814 AC_VERB_SET_PIN_WIDGET_CONTROL,
10815 val ? PIN_HP : 0);
10816 /* mono (speaker) depending on the HP jack sense */
10817 val = val && !spec->jack_present;
10818 snd_hda_codec_write_cache(codec, 0x16, 0,
10819 AC_VERB_SET_PIN_WIDGET_CONTROL,
10820 val ? PIN_OUT : 0);
10821}
10822
10823static void alc262_hp_bpc_automute(struct hda_codec *codec)
10824{
10825 struct alc_spec *spec = codec->spec;
864f92be
WF
10826
10827 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10828 alc262_hp_master_update(codec);
10829}
10830
10831static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10832{
10833 if ((res >> 26) != ALC880_HP_EVENT)
10834 return;
10835 alc262_hp_bpc_automute(codec);
10836}
10837
10838static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10839{
10840 struct alc_spec *spec = codec->spec;
864f92be
WF
10841
10842 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10843 alc262_hp_master_update(codec);
10844}
10845
10846static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10847 unsigned int res)
10848{
10849 if ((res >> 26) != ALC880_HP_EVENT)
10850 return;
10851 alc262_hp_wildwest_automute(codec);
10852}
10853
b72519b5 10854#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10855
10856static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10857 struct snd_ctl_elem_value *ucontrol)
10858{
10859 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10860 struct alc_spec *spec = codec->spec;
10861 int val = !!*ucontrol->value.integer.value;
10862
10863 if (val == spec->master_sw)
10864 return 0;
10865 spec->master_sw = val;
10866 alc262_hp_master_update(codec);
10867 return 1;
10868}
10869
b72519b5
TI
10870#define ALC262_HP_MASTER_SWITCH \
10871 { \
10872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10873 .name = "Master Playback Switch", \
10874 .info = snd_ctl_boolean_mono_info, \
10875 .get = alc262_hp_master_sw_get, \
10876 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10877 }, \
10878 { \
10879 .iface = NID_MAPPING, \
10880 .name = "Master Playback Switch", \
10881 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10882 }
10883
5b0cb1d8 10884
9c7f852e 10885static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10886 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10888 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10889 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10890 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10891 HDA_OUTPUT),
10892 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10893 HDA_OUTPUT),
9c7f852e
TI
10894 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10895 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10896 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10897 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10898 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10899 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10902 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10903 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10904 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10905 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10906 { } /* end */
10907};
10908
cd7509a4 10909static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10910 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10912 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10913 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10914 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10915 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10916 HDA_OUTPUT),
10917 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10918 HDA_OUTPUT),
cd7509a4
KY
10919 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10920 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10921 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10922 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10923 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10924 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10925 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10926 { } /* end */
10927};
10928
10929static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10930 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10931 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10932 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10933 { } /* end */
10934};
10935
66d2a9d6 10936/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10937static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10938{
10939 struct alc_spec *spec = codec->spec;
66d2a9d6 10940
a9fd4f3f 10941 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10942 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10943}
10944
66d2a9d6 10945static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10946 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10947 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10948 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10949 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10950 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10952 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10953 { } /* end */
10954};
10955
10956static struct hda_verb alc262_hp_t5735_verbs[] = {
10957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10958 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10959
10960 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10961 { }
10962};
10963
8c427226 10964static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
10965 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
10967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10968 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
10969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10971 { } /* end */
10972};
10973
10974static struct hda_verb alc262_hp_rp5700_verbs[] = {
10975 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10976 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10979 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10980 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10982 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10985 {}
10986};
10987
10988static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10989 .num_items = 1,
10990 .items = {
10991 { "Line", 0x1 },
10992 },
10993};
10994
42171c17
TI
10995/* bind hp and internal speaker mute (with plug check) as master switch */
10996static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 10997{
42171c17
TI
10998 struct alc_spec *spec = codec->spec;
10999 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11000 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11001 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11002 unsigned int mute;
0724ea2a 11003
42171c17
TI
11004 /* HP */
11005 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11006 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11007 HDA_AMP_MUTE, mute);
11008 /* mute internal speaker per jack sense */
11009 if (spec->jack_present)
11010 mute = HDA_AMP_MUTE;
11011 if (line_nid)
11012 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11013 HDA_AMP_MUTE, mute);
11014 if (speaker_nid && speaker_nid != line_nid)
11015 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11016 HDA_AMP_MUTE, mute);
42171c17
TI
11017}
11018
11019#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11020
11021static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11022 struct snd_ctl_elem_value *ucontrol)
11023{
11024 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11025 struct alc_spec *spec = codec->spec;
11026 int val = !!*ucontrol->value.integer.value;
11027
11028 if (val == spec->master_sw)
11029 return 0;
11030 spec->master_sw = val;
11031 alc262_hippo_master_update(codec);
11032 return 1;
11033}
11034
11035#define ALC262_HIPPO_MASTER_SWITCH \
11036 { \
11037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11038 .name = "Master Playback Switch", \
11039 .info = snd_ctl_boolean_mono_info, \
11040 .get = alc262_hippo_master_sw_get, \
11041 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11042 }, \
11043 { \
11044 .iface = NID_MAPPING, \
11045 .name = "Master Playback Switch", \
11046 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11047 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11048 }
42171c17
TI
11049
11050static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11051 ALC262_HIPPO_MASTER_SWITCH,
11052 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11059 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11060 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11061 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11062 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11063 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11064 { } /* end */
11065};
11066
11067static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11068 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11069 ALC262_HIPPO_MASTER_SWITCH,
11070 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11071 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11072 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11073 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11076 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11077 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11078 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11079 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11080 { } /* end */
11081};
11082
11083/* mute/unmute internal speaker according to the hp jack and mute state */
11084static void alc262_hippo_automute(struct hda_codec *codec)
11085{
11086 struct alc_spec *spec = codec->spec;
11087 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11088
864f92be 11089 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11090 alc262_hippo_master_update(codec);
0724ea2a 11091}
5b31954e 11092
42171c17
TI
11093static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11094{
11095 if ((res >> 26) != ALC880_HP_EVENT)
11096 return;
11097 alc262_hippo_automute(codec);
11098}
11099
4f5d1706 11100static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11101{
11102 struct alc_spec *spec = codec->spec;
11103
11104 spec->autocfg.hp_pins[0] = 0x15;
11105 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11106}
11107
4f5d1706 11108static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11109{
11110 struct alc_spec *spec = codec->spec;
11111
11112 spec->autocfg.hp_pins[0] = 0x1b;
11113 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11114}
11115
11116
272a527c 11117static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11118 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11119 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11121 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11122 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11123 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11124 { } /* end */
11125};
11126
83c34218 11127static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11128 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11129 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11130 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11133 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11134 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11135 { } /* end */
11136};
272a527c 11137
ba340e82
TV
11138static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11139 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11140 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11141 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11142 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11147 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11148 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11149 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11150 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11151 { } /* end */
11152};
11153
11154static struct hda_verb alc262_tyan_verbs[] = {
11155 /* Headphone automute */
11156 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11157 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11158 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11159
11160 /* P11 AUX_IN, white 4-pin connector */
11161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11162 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11163 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11164 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11165
11166 {}
11167};
11168
11169/* unsolicited event for HP jack sensing */
4f5d1706 11170static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11171{
a9fd4f3f 11172 struct alc_spec *spec = codec->spec;
ba340e82 11173
a9fd4f3f
TI
11174 spec->autocfg.hp_pins[0] = 0x1b;
11175 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11176}
11177
ba340e82 11178
9c7f852e
TI
11179#define alc262_capture_mixer alc882_capture_mixer
11180#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11181
11182/*
11183 * generic initialization of ADC, input mixers and output mixers
11184 */
11185static struct hda_verb alc262_init_verbs[] = {
11186 /*
11187 * Unmute ADC0-2 and set the default input to mic-in
11188 */
11189 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11191 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11192 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11193 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11194 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11195
cb53c626 11196 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11197 * mixer widget
f12ab1e0
TI
11198 * Note: PASD motherboards uses the Line In 2 as the input for
11199 * front panel mic (mic 2)
9c7f852e
TI
11200 */
11201 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11202 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11203 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11204 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11205 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11206 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11207
11208 /*
df694daa
KY
11209 * Set up output mixers (0x0c - 0x0e)
11210 */
11211 /* set vol=0 to output mixers */
11212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11213 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11215 /* set up input amps for analog loopback */
11216 /* Amp Indices: DAC = 0, mixer = 1 */
11217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11223
11224 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11225 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11226 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11227 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11228 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11229 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11230
11231 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11232 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11233 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11235 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11236
df694daa
KY
11237 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11239
df694daa
KY
11240 /* FIXME: use matrix-type input source selection */
11241 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11242 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11243 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11247 /* Input mixer2 */
11248 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11249 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11250 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11251 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11252 /* Input mixer3 */
11253 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11254 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11255 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11256 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11257
11258 { }
11259};
1da177e4 11260
4e555fe5
KY
11261static struct hda_verb alc262_eapd_verbs[] = {
11262 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11263 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11264 { }
11265};
11266
ccc656ce
KY
11267static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11268 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11269 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11270 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11271
11272 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11274 {}
11275};
11276
272a527c
KY
11277static struct hda_verb alc262_sony_unsol_verbs[] = {
11278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11279 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11280 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11281
11282 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11284 {}
272a527c
KY
11285};
11286
4e555fe5
KY
11287static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11288 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11289 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11292 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11293 { } /* end */
11294};
11295
11296static struct hda_verb alc262_toshiba_s06_verbs[] = {
11297 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11298 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11301 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11305 {}
11306};
11307
4f5d1706 11308static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11309{
a9fd4f3f
TI
11310 struct alc_spec *spec = codec->spec;
11311
11312 spec->autocfg.hp_pins[0] = 0x15;
11313 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11314 spec->ext_mic.pin = 0x18;
11315 spec->ext_mic.mux_idx = 0;
11316 spec->int_mic.pin = 0x12;
11317 spec->int_mic.mux_idx = 9;
11318 spec->auto_mic = 1;
4e555fe5
KY
11319}
11320
e8f9ae2a
PT
11321/*
11322 * nec model
11323 * 0x15 = headphone
11324 * 0x16 = internal speaker
11325 * 0x18 = external mic
11326 */
11327
11328static struct snd_kcontrol_new alc262_nec_mixer[] = {
11329 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11330 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11331
11332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11334 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11335
11336 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11337 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11338 { } /* end */
11339};
11340
11341static struct hda_verb alc262_nec_verbs[] = {
11342 /* Unmute Speaker */
11343 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11344
11345 /* Headphone */
11346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11348
11349 /* External mic to headphone */
11350 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11351 /* External mic to speaker */
11352 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11353 {}
11354};
11355
834be88d
TI
11356/*
11357 * fujitsu model
5d9fab2d
TV
11358 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11359 * 0x1b = port replicator headphone out
834be88d
TI
11360 */
11361
11362#define ALC_HP_EVENT 0x37
11363
11364static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11365 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11366 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11367 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11368 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11369 {}
11370};
11371
0e31daf7
J
11372static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11373 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11374 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11375 {}
11376};
11377
e2595322
DC
11378static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11379 /* Front Mic pin: input vref at 50% */
11380 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11381 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11382 {}
11383};
11384
834be88d 11385static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11386 .num_items = 3,
834be88d
TI
11387 .items = {
11388 { "Mic", 0x0 },
39d3ed38 11389 { "Int Mic", 0x1 },
834be88d
TI
11390 { "CD", 0x4 },
11391 },
11392};
11393
9c7f852e
TI
11394static struct hda_input_mux alc262_HP_capture_source = {
11395 .num_items = 5,
11396 .items = {
11397 { "Mic", 0x0 },
accbe498 11398 { "Front Mic", 0x1 },
9c7f852e
TI
11399 { "Line", 0x2 },
11400 { "CD", 0x4 },
11401 { "AUX IN", 0x6 },
11402 },
11403};
11404
accbe498 11405static struct hda_input_mux alc262_HP_D7000_capture_source = {
11406 .num_items = 4,
11407 .items = {
11408 { "Mic", 0x0 },
11409 { "Front Mic", 0x2 },
11410 { "Line", 0x1 },
11411 { "CD", 0x4 },
11412 },
11413};
11414
ebc7a406 11415/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11416static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11417{
11418 struct alc_spec *spec = codec->spec;
11419 unsigned int mute;
11420
f12ab1e0 11421 if (force || !spec->sense_updated) {
864f92be
WF
11422 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11423 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11424 spec->sense_updated = 1;
11425 }
ebc7a406
TI
11426 /* unmute internal speaker only if both HPs are unplugged and
11427 * master switch is on
11428 */
11429 if (spec->jack_present)
11430 mute = HDA_AMP_MUTE;
11431 else
834be88d 11432 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11433 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11434 HDA_AMP_MUTE, mute);
834be88d
TI
11435}
11436
11437/* unsolicited event for HP jack sensing */
11438static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11439 unsigned int res)
11440{
11441 if ((res >> 26) != ALC_HP_EVENT)
11442 return;
11443 alc262_fujitsu_automute(codec, 1);
11444}
11445
ebc7a406
TI
11446static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11447{
11448 alc262_fujitsu_automute(codec, 1);
11449}
11450
834be88d 11451/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11452static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11453 .ops = &snd_hda_bind_vol,
11454 .values = {
11455 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11456 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11457 0
11458 },
11459};
834be88d 11460
0e31daf7
J
11461/* mute/unmute internal speaker according to the hp jack and mute state */
11462static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11463{
11464 struct alc_spec *spec = codec->spec;
11465 unsigned int mute;
11466
11467 if (force || !spec->sense_updated) {
864f92be 11468 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11469 spec->sense_updated = 1;
11470 }
11471 if (spec->jack_present) {
11472 /* mute internal speaker */
11473 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11474 HDA_AMP_MUTE, HDA_AMP_MUTE);
11475 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11476 HDA_AMP_MUTE, HDA_AMP_MUTE);
11477 } else {
11478 /* unmute internal speaker if necessary */
11479 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11480 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11481 HDA_AMP_MUTE, mute);
11482 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11483 HDA_AMP_MUTE, mute);
11484 }
11485}
11486
11487/* unsolicited event for HP jack sensing */
11488static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11489 unsigned int res)
11490{
11491 if ((res >> 26) != ALC_HP_EVENT)
11492 return;
11493 alc262_lenovo_3000_automute(codec, 1);
11494}
11495
8de56b7d
TI
11496static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11497 int dir, int idx, long *valp)
11498{
11499 int i, change = 0;
11500
11501 for (i = 0; i < 2; i++, valp++)
11502 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11503 HDA_AMP_MUTE,
11504 *valp ? 0 : HDA_AMP_MUTE);
11505 return change;
11506}
11507
834be88d
TI
11508/* bind hp and internal speaker mute (with plug check) */
11509static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11510 struct snd_ctl_elem_value *ucontrol)
11511{
11512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11513 long *valp = ucontrol->value.integer.value;
11514 int change;
11515
8de56b7d
TI
11516 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11517 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11518 if (change)
11519 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11520 return change;
11521}
11522
11523static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11524 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11525 {
11526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11527 .name = "Master Playback Switch",
5e26dfd0 11528 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11529 .info = snd_hda_mixer_amp_switch_info,
11530 .get = snd_hda_mixer_amp_switch_get,
11531 .put = alc262_fujitsu_master_sw_put,
11532 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11533 },
5b0cb1d8
JK
11534 {
11535 .iface = NID_MAPPING,
11536 .name = "Master Playback Switch",
11537 .private_value = 0x1b,
11538 },
834be88d
TI
11539 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11540 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11541 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11543 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11544 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11545 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11546 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11547 { } /* end */
11548};
11549
0e31daf7
J
11550/* bind hp and internal speaker mute (with plug check) */
11551static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11552 struct snd_ctl_elem_value *ucontrol)
11553{
11554 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11555 long *valp = ucontrol->value.integer.value;
11556 int change;
11557
8de56b7d 11558 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11559 if (change)
11560 alc262_lenovo_3000_automute(codec, 0);
11561 return change;
11562}
11563
11564static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11565 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11566 {
11567 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11568 .name = "Master Playback Switch",
5e26dfd0 11569 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11570 .info = snd_hda_mixer_amp_switch_info,
11571 .get = snd_hda_mixer_amp_switch_get,
11572 .put = alc262_lenovo_3000_master_sw_put,
11573 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11574 },
11575 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11576 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11577 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11580 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11581 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11582 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11583 { } /* end */
11584};
11585
9f99a638
HM
11586static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11587 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11588 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11591 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11592 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11593 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11594 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11595 { } /* end */
11596};
11597
304dcaac
TI
11598/* additional init verbs for Benq laptops */
11599static struct hda_verb alc262_EAPD_verbs[] = {
11600 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11601 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11602 {}
11603};
11604
83c34218
KY
11605static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11606 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11608
11609 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11610 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11611 {}
11612};
11613
f651b50b
TD
11614/* Samsung Q1 Ultra Vista model setup */
11615static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11616 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11617 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11620 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11621 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11622 { } /* end */
11623};
11624
11625static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11626 /* output mixer */
11627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11629 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11630 /* speaker */
11631 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11633 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11634 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11635 /* HP */
f651b50b 11636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11639 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11640 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11641 /* internal mic */
11642 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11644 /* ADC, choose mic */
11645 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11651 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11655 {}
11656};
11657
f651b50b
TD
11658/* mute/unmute internal speaker according to the hp jack and mute state */
11659static void alc262_ultra_automute(struct hda_codec *codec)
11660{
11661 struct alc_spec *spec = codec->spec;
11662 unsigned int mute;
f651b50b 11663
bb9f76cd
TI
11664 mute = 0;
11665 /* auto-mute only when HP is used as HP */
11666 if (!spec->cur_mux[0]) {
864f92be 11667 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11668 if (spec->jack_present)
11669 mute = HDA_AMP_MUTE;
f651b50b 11670 }
bb9f76cd
TI
11671 /* mute/unmute internal speaker */
11672 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11673 HDA_AMP_MUTE, mute);
11674 /* mute/unmute HP */
11675 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11676 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11677}
11678
11679/* unsolicited event for HP jack sensing */
11680static void alc262_ultra_unsol_event(struct hda_codec *codec,
11681 unsigned int res)
11682{
11683 if ((res >> 26) != ALC880_HP_EVENT)
11684 return;
11685 alc262_ultra_automute(codec);
11686}
11687
bb9f76cd
TI
11688static struct hda_input_mux alc262_ultra_capture_source = {
11689 .num_items = 2,
11690 .items = {
11691 { "Mic", 0x1 },
11692 { "Headphone", 0x7 },
11693 },
11694};
11695
11696static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11697 struct snd_ctl_elem_value *ucontrol)
11698{
11699 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11700 struct alc_spec *spec = codec->spec;
11701 int ret;
11702
54cbc9ab 11703 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11704 if (!ret)
11705 return 0;
11706 /* reprogram the HP pin as mic or HP according to the input source */
11707 snd_hda_codec_write_cache(codec, 0x15, 0,
11708 AC_VERB_SET_PIN_WIDGET_CONTROL,
11709 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11710 alc262_ultra_automute(codec); /* mute/unmute HP */
11711 return ret;
11712}
11713
11714static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11715 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11716 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11717 {
11718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11719 .name = "Capture Source",
54cbc9ab
TI
11720 .info = alc_mux_enum_info,
11721 .get = alc_mux_enum_get,
bb9f76cd
TI
11722 .put = alc262_ultra_mux_enum_put,
11723 },
5b0cb1d8
JK
11724 {
11725 .iface = NID_MAPPING,
11726 .name = "Capture Source",
11727 .private_value = 0x15,
11728 },
bb9f76cd
TI
11729 { } /* end */
11730};
11731
c3fc1f50
TI
11732/* We use two mixers depending on the output pin; 0x16 is a mono output
11733 * and thus it's bound with a different mixer.
11734 * This function returns which mixer amp should be used.
11735 */
11736static int alc262_check_volbit(hda_nid_t nid)
11737{
11738 if (!nid)
11739 return 0;
11740 else if (nid == 0x16)
11741 return 2;
11742 else
11743 return 1;
11744}
11745
11746static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11747 const char *pfx, int *vbits)
11748{
c3fc1f50
TI
11749 unsigned long val;
11750 int vbit;
11751
11752 vbit = alc262_check_volbit(nid);
11753 if (!vbit)
11754 return 0;
11755 if (*vbits & vbit) /* a volume control for this mixer already there */
11756 return 0;
11757 *vbits |= vbit;
c3fc1f50
TI
11758 if (vbit == 2)
11759 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11760 else
11761 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11762 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11763}
11764
11765static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11766 const char *pfx)
11767{
c3fc1f50
TI
11768 unsigned long val;
11769
11770 if (!nid)
11771 return 0;
c3fc1f50
TI
11772 if (nid == 0x16)
11773 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11774 else
11775 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11776 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11777}
11778
df694daa 11779/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11780static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11781 const struct auto_pin_cfg *cfg)
df694daa 11782{
c3fc1f50
TI
11783 const char *pfx;
11784 int vbits;
df694daa
KY
11785 int err;
11786
11787 spec->multiout.num_dacs = 1; /* only use one dac */
11788 spec->multiout.dac_nids = spec->private_dac_nids;
11789 spec->multiout.dac_nids[0] = 2;
11790
c3fc1f50
TI
11791 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11792 pfx = "Master";
11793 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11794 pfx = "Speaker";
11795 else
11796 pfx = "Front";
11797 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11798 if (err < 0)
11799 return err;
11800 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11801 if (err < 0)
11802 return err;
11803 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11804 if (err < 0)
11805 return err;
df694daa 11806
c3fc1f50
TI
11807 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11808 alc262_check_volbit(cfg->speaker_pins[0]) |
11809 alc262_check_volbit(cfg->hp_pins[0]);
11810 if (vbits == 1 || vbits == 2)
11811 pfx = "Master"; /* only one mixer is used */
11812 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11813 pfx = "Speaker";
11814 else
11815 pfx = "Front";
11816 vbits = 0;
11817 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11818 if (err < 0)
11819 return err;
11820 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11821 &vbits);
11822 if (err < 0)
11823 return err;
11824 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11825 &vbits);
11826 if (err < 0)
11827 return err;
f12ab1e0 11828 return 0;
df694daa
KY
11829}
11830
05f5f477 11831#define alc262_auto_create_input_ctls \
eaa9b3a7 11832 alc882_auto_create_input_ctls
df694daa
KY
11833
11834/*
11835 * generic initialization of ADC, input mixers and output mixers
11836 */
11837static struct hda_verb alc262_volume_init_verbs[] = {
11838 /*
11839 * Unmute ADC0-2 and set the default input to mic-in
11840 */
11841 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11842 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11843 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11844 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11845 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11846 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11847
cb53c626 11848 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11849 * mixer widget
f12ab1e0
TI
11850 * Note: PASD motherboards uses the Line In 2 as the input for
11851 * front panel mic (mic 2)
df694daa
KY
11852 */
11853 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11854 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11855 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11858 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11859
11860 /*
11861 * Set up output mixers (0x0c - 0x0f)
11862 */
11863 /* set vol=0 to output mixers */
11864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11866 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11867
df694daa
KY
11868 /* set up input amps for analog loopback */
11869 /* Amp Indices: DAC = 0, mixer = 1 */
11870 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11871 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11872 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11873 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11874 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11875 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11876
11877 /* FIXME: use matrix-type input source selection */
11878 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11879 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11880 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11881 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11883 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11884 /* Input mixer2 */
11885 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11889 /* Input mixer3 */
11890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11891 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11894
11895 { }
11896};
11897
9c7f852e
TI
11898static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11899 /*
11900 * Unmute ADC0-2 and set the default input to mic-in
11901 */
11902 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11903 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11904 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11905 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11906 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11908
cb53c626 11909 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11910 * mixer widget
f12ab1e0
TI
11911 * Note: PASD motherboards uses the Line In 2 as the input for
11912 * front panel mic (mic 2)
9c7f852e
TI
11913 */
11914 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11915 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11916 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11917 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11918 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11922
9c7f852e
TI
11923 /*
11924 * Set up output mixers (0x0c - 0x0e)
11925 */
11926 /* set vol=0 to output mixers */
11927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11928 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11929 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11930
11931 /* set up input amps for analog loopback */
11932 /* Amp Indices: DAC = 0, mixer = 1 */
11933 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11935 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11936 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11937 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11938 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11939
ce875f07 11940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11942 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11943
11944 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11945 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11946
11947 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11948 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11949
11950 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11952 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11954 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11955
0e4835c1 11956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11957 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11958 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11959 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11960 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11961 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11962
11963
11964 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
11965 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11966 /* Input mixer1: only unmute Mic */
9c7f852e 11967 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11973 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11976 /* Input mixer2 */
11977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11978 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11979 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11982 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11985 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
11986 /* Input mixer3 */
11987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11990 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11991 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 11996
ce875f07
TI
11997 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11998
9c7f852e
TI
11999 { }
12000};
12001
cd7509a4
KY
12002static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12003 /*
12004 * Unmute ADC0-2 and set the default input to mic-in
12005 */
12006 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12007 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12008 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12009 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12010 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12012
cb53c626 12013 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12014 * mixer widget
12015 * Note: PASD motherboards uses the Line In 2 as the input for front
12016 * panel mic (mic 2)
12017 */
12018 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12027 /*
12028 * Set up output mixers (0x0c - 0x0e)
12029 */
12030 /* set vol=0 to output mixers */
12031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12032 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12034
12035 /* set up input amps for analog loopback */
12036 /* Amp Indices: DAC = 0, mixer = 1 */
12037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12039 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12041 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12042 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12043
12044
12045 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12046 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12048 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12049 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12050 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12051 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12052
12053 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12055
12056 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12057 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12058
12059 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12061 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12062 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12063 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12064 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12065
12066 /* FIXME: use matrix-type input source selection */
12067 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12068 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12071 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12074 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12076 /* Input mixer2 */
12077 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12079 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12082 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12084 /* Input mixer3 */
12085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12090 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12092
ce875f07
TI
12093 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12094
cd7509a4
KY
12095 { }
12096};
12097
9f99a638
HM
12098static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12099
12100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12103
12104 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12105 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12106 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12107 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12108
12109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12111 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12112 {}
12113};
12114
12115
cb53c626
TI
12116#ifdef CONFIG_SND_HDA_POWER_SAVE
12117#define alc262_loopbacks alc880_loopbacks
12118#endif
12119
def319f9 12120/* pcm configuration: identical with ALC880 */
df694daa
KY
12121#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12122#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12123#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12124#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12125
12126/*
12127 * BIOS auto configuration
12128 */
12129static int alc262_parse_auto_config(struct hda_codec *codec)
12130{
12131 struct alc_spec *spec = codec->spec;
12132 int err;
12133 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12134
f12ab1e0
TI
12135 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12136 alc262_ignore);
12137 if (err < 0)
df694daa 12138 return err;
e64f14f4 12139 if (!spec->autocfg.line_outs) {
0852d7a6 12140 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12141 spec->multiout.max_channels = 2;
12142 spec->no_analog = 1;
12143 goto dig_only;
12144 }
df694daa 12145 return 0; /* can't find valid BIOS pin config */
e64f14f4 12146 }
f12ab1e0
TI
12147 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12148 if (err < 0)
12149 return err;
05f5f477 12150 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12151 if (err < 0)
df694daa
KY
12152 return err;
12153
12154 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12155
e64f14f4 12156 dig_only:
0852d7a6 12157 if (spec->autocfg.dig_outs) {
df694daa 12158 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 12159 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 12160 }
df694daa
KY
12161 if (spec->autocfg.dig_in_pin)
12162 spec->dig_in_nid = ALC262_DIGIN_NID;
12163
603c4019 12164 if (spec->kctls.list)
d88897ea 12165 add_mixer(spec, spec->kctls.list);
df694daa 12166
d88897ea 12167 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12168 spec->num_mux_defs = 1;
61b9b9b1 12169 spec->input_mux = &spec->private_imux[0];
df694daa 12170
776e184e
TI
12171 err = alc_auto_add_mic_boost(codec);
12172 if (err < 0)
12173 return err;
12174
6227cdce 12175 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12176
df694daa
KY
12177 return 1;
12178}
12179
12180#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12181#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12182#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12183#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12184
12185
12186/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12187static void alc262_auto_init(struct hda_codec *codec)
df694daa 12188{
f6c7e546 12189 struct alc_spec *spec = codec->spec;
df694daa
KY
12190 alc262_auto_init_multi_out(codec);
12191 alc262_auto_init_hp_out(codec);
12192 alc262_auto_init_analog_input(codec);
f511b01c 12193 alc262_auto_init_input_src(codec);
f6c7e546 12194 if (spec->unsol_event)
7fb0d78f 12195 alc_inithook(codec);
df694daa
KY
12196}
12197
12198/*
12199 * configuration and preset
12200 */
f5fcc13c
TI
12201static const char *alc262_models[ALC262_MODEL_LAST] = {
12202 [ALC262_BASIC] = "basic",
12203 [ALC262_HIPPO] = "hippo",
12204 [ALC262_HIPPO_1] = "hippo_1",
12205 [ALC262_FUJITSU] = "fujitsu",
12206 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12207 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12208 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12209 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12210 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12211 [ALC262_BENQ_T31] = "benq-t31",
12212 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12213 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12214 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12215 [ALC262_ULTRA] = "ultra",
0e31daf7 12216 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12217 [ALC262_NEC] = "nec",
ba340e82 12218 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12219 [ALC262_AUTO] = "auto",
12220};
12221
12222static struct snd_pci_quirk alc262_cfg_tbl[] = {
12223 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12224 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12225 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12226 ALC262_HP_BPC),
12227 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12228 ALC262_HP_BPC),
53eff7e1
TI
12229 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12230 ALC262_HP_BPC),
cd7509a4 12231 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12232 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12233 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12234 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12235 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12236 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12237 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12238 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12239 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12240 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12241 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12242 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12243 ALC262_HP_TC_T5735),
8c427226 12244 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12245 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12246 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12247 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12248 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12249 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12250 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12251 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12252#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12253 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12254 ALC262_SONY_ASSAMD),
c5b5165c 12255#endif
36ca6e13 12256 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12257 ALC262_TOSHIBA_RX1),
80ffe869 12258 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12259 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12260 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12261 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12262 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12263 ALC262_ULTRA),
3e420e78 12264 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12265 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12266 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12267 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12268 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12269 {}
12270};
12271
12272static struct alc_config_preset alc262_presets[] = {
12273 [ALC262_BASIC] = {
12274 .mixers = { alc262_base_mixer },
12275 .init_verbs = { alc262_init_verbs },
12276 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12277 .dac_nids = alc262_dac_nids,
12278 .hp_nid = 0x03,
12279 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12280 .channel_mode = alc262_modes,
a3bcba38 12281 .input_mux = &alc262_capture_source,
df694daa 12282 },
ccc656ce 12283 [ALC262_HIPPO] = {
42171c17 12284 .mixers = { alc262_hippo_mixer },
6732bd0d 12285 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12286 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12287 .dac_nids = alc262_dac_nids,
12288 .hp_nid = 0x03,
12289 .dig_out_nid = ALC262_DIGOUT_NID,
12290 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12291 .channel_mode = alc262_modes,
12292 .input_mux = &alc262_capture_source,
12293 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12294 .setup = alc262_hippo_setup,
12295 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12296 },
12297 [ALC262_HIPPO_1] = {
12298 .mixers = { alc262_hippo1_mixer },
12299 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12300 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12301 .dac_nids = alc262_dac_nids,
12302 .hp_nid = 0x02,
12303 .dig_out_nid = ALC262_DIGOUT_NID,
12304 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12305 .channel_mode = alc262_modes,
12306 .input_mux = &alc262_capture_source,
42171c17 12307 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12308 .setup = alc262_hippo1_setup,
12309 .init_hook = alc262_hippo_automute,
ccc656ce 12310 },
834be88d
TI
12311 [ALC262_FUJITSU] = {
12312 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12313 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12314 alc262_fujitsu_unsol_verbs },
834be88d
TI
12315 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12316 .dac_nids = alc262_dac_nids,
12317 .hp_nid = 0x03,
12318 .dig_out_nid = ALC262_DIGOUT_NID,
12319 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12320 .channel_mode = alc262_modes,
12321 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12322 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12323 .init_hook = alc262_fujitsu_init_hook,
834be88d 12324 },
9c7f852e
TI
12325 [ALC262_HP_BPC] = {
12326 .mixers = { alc262_HP_BPC_mixer },
12327 .init_verbs = { alc262_HP_BPC_init_verbs },
12328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12329 .dac_nids = alc262_dac_nids,
12330 .hp_nid = 0x03,
12331 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12332 .channel_mode = alc262_modes,
12333 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12334 .unsol_event = alc262_hp_bpc_unsol_event,
12335 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12336 },
cd7509a4
KY
12337 [ALC262_HP_BPC_D7000_WF] = {
12338 .mixers = { alc262_HP_BPC_WildWest_mixer },
12339 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12340 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12341 .dac_nids = alc262_dac_nids,
12342 .hp_nid = 0x03,
12343 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12344 .channel_mode = alc262_modes,
accbe498 12345 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12346 .unsol_event = alc262_hp_wildwest_unsol_event,
12347 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12348 },
cd7509a4
KY
12349 [ALC262_HP_BPC_D7000_WL] = {
12350 .mixers = { alc262_HP_BPC_WildWest_mixer,
12351 alc262_HP_BPC_WildWest_option_mixer },
12352 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12353 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12354 .dac_nids = alc262_dac_nids,
12355 .hp_nid = 0x03,
12356 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12357 .channel_mode = alc262_modes,
accbe498 12358 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12359 .unsol_event = alc262_hp_wildwest_unsol_event,
12360 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12361 },
66d2a9d6
KY
12362 [ALC262_HP_TC_T5735] = {
12363 .mixers = { alc262_hp_t5735_mixer },
12364 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12365 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12366 .dac_nids = alc262_dac_nids,
12367 .hp_nid = 0x03,
12368 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12369 .channel_mode = alc262_modes,
12370 .input_mux = &alc262_capture_source,
dc99be47 12371 .unsol_event = alc_sku_unsol_event,
4f5d1706 12372 .setup = alc262_hp_t5735_setup,
dc99be47 12373 .init_hook = alc_inithook,
8c427226
KY
12374 },
12375 [ALC262_HP_RP5700] = {
12376 .mixers = { alc262_hp_rp5700_mixer },
12377 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12378 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12379 .dac_nids = alc262_dac_nids,
12380 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12381 .channel_mode = alc262_modes,
12382 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12383 },
304dcaac
TI
12384 [ALC262_BENQ_ED8] = {
12385 .mixers = { alc262_base_mixer },
12386 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12387 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12388 .dac_nids = alc262_dac_nids,
12389 .hp_nid = 0x03,
12390 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12391 .channel_mode = alc262_modes,
12392 .input_mux = &alc262_capture_source,
f12ab1e0 12393 },
272a527c
KY
12394 [ALC262_SONY_ASSAMD] = {
12395 .mixers = { alc262_sony_mixer },
12396 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12397 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12398 .dac_nids = alc262_dac_nids,
12399 .hp_nid = 0x02,
12400 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12401 .channel_mode = alc262_modes,
12402 .input_mux = &alc262_capture_source,
12403 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12404 .setup = alc262_hippo_setup,
12405 .init_hook = alc262_hippo_automute,
83c34218
KY
12406 },
12407 [ALC262_BENQ_T31] = {
12408 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12409 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12410 alc_hp15_unsol_verbs },
83c34218
KY
12411 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12412 .dac_nids = alc262_dac_nids,
12413 .hp_nid = 0x03,
12414 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12415 .channel_mode = alc262_modes,
12416 .input_mux = &alc262_capture_source,
12417 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12418 .setup = alc262_hippo_setup,
12419 .init_hook = alc262_hippo_automute,
ea1fb29a 12420 },
f651b50b 12421 [ALC262_ULTRA] = {
f9e336f6
TI
12422 .mixers = { alc262_ultra_mixer },
12423 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12424 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12425 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12426 .dac_nids = alc262_dac_nids,
f651b50b
TD
12427 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12428 .channel_mode = alc262_modes,
12429 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12430 .adc_nids = alc262_adc_nids, /* ADC0 */
12431 .capsrc_nids = alc262_capsrc_nids,
12432 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12433 .unsol_event = alc262_ultra_unsol_event,
12434 .init_hook = alc262_ultra_automute,
12435 },
0e31daf7
J
12436 [ALC262_LENOVO_3000] = {
12437 .mixers = { alc262_lenovo_3000_mixer },
12438 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12439 alc262_lenovo_3000_unsol_verbs,
12440 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12441 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12442 .dac_nids = alc262_dac_nids,
12443 .hp_nid = 0x03,
12444 .dig_out_nid = ALC262_DIGOUT_NID,
12445 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12446 .channel_mode = alc262_modes,
12447 .input_mux = &alc262_fujitsu_capture_source,
12448 .unsol_event = alc262_lenovo_3000_unsol_event,
12449 },
e8f9ae2a
PT
12450 [ALC262_NEC] = {
12451 .mixers = { alc262_nec_mixer },
12452 .init_verbs = { alc262_nec_verbs },
12453 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12454 .dac_nids = alc262_dac_nids,
12455 .hp_nid = 0x03,
12456 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12457 .channel_mode = alc262_modes,
12458 .input_mux = &alc262_capture_source,
12459 },
4e555fe5
KY
12460 [ALC262_TOSHIBA_S06] = {
12461 .mixers = { alc262_toshiba_s06_mixer },
12462 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12463 alc262_eapd_verbs },
12464 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12465 .capsrc_nids = alc262_dmic_capsrc_nids,
12466 .dac_nids = alc262_dac_nids,
12467 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12468 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12469 .dig_out_nid = ALC262_DIGOUT_NID,
12470 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12471 .channel_mode = alc262_modes,
4f5d1706
TI
12472 .unsol_event = alc_sku_unsol_event,
12473 .setup = alc262_toshiba_s06_setup,
12474 .init_hook = alc_inithook,
4e555fe5 12475 },
9f99a638
HM
12476 [ALC262_TOSHIBA_RX1] = {
12477 .mixers = { alc262_toshiba_rx1_mixer },
12478 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12479 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12480 .dac_nids = alc262_dac_nids,
12481 .hp_nid = 0x03,
12482 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12483 .channel_mode = alc262_modes,
12484 .input_mux = &alc262_capture_source,
12485 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12486 .setup = alc262_hippo_setup,
12487 .init_hook = alc262_hippo_automute,
9f99a638 12488 },
ba340e82
TV
12489 [ALC262_TYAN] = {
12490 .mixers = { alc262_tyan_mixer },
12491 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12492 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12493 .dac_nids = alc262_dac_nids,
12494 .hp_nid = 0x02,
12495 .dig_out_nid = ALC262_DIGOUT_NID,
12496 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12497 .channel_mode = alc262_modes,
12498 .input_mux = &alc262_capture_source,
a9fd4f3f 12499 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12500 .setup = alc262_tyan_setup,
12501 .init_hook = alc_automute_amp,
ba340e82 12502 },
df694daa
KY
12503};
12504
12505static int patch_alc262(struct hda_codec *codec)
12506{
12507 struct alc_spec *spec;
12508 int board_config;
12509 int err;
12510
dc041e0b 12511 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12512 if (spec == NULL)
12513 return -ENOMEM;
12514
12515 codec->spec = spec;
12516#if 0
f12ab1e0
TI
12517 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12518 * under-run
12519 */
df694daa
KY
12520 {
12521 int tmp;
12522 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12523 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12524 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12525 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12526 }
12527#endif
da00c244 12528 alc_auto_parse_customize_define(codec);
df694daa 12529
2c3bf9ab
TI
12530 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12531
f5fcc13c
TI
12532 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12533 alc262_models,
12534 alc262_cfg_tbl);
cd7509a4 12535
f5fcc13c 12536 if (board_config < 0) {
9a11f1aa
TI
12537 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12538 codec->chip_name);
df694daa
KY
12539 board_config = ALC262_AUTO;
12540 }
12541
12542 if (board_config == ALC262_AUTO) {
12543 /* automatic parse from the BIOS config */
12544 err = alc262_parse_auto_config(codec);
12545 if (err < 0) {
12546 alc_free(codec);
12547 return err;
f12ab1e0 12548 } else if (!err) {
9c7f852e
TI
12549 printk(KERN_INFO
12550 "hda_codec: Cannot set up configuration "
12551 "from BIOS. Using base mode...\n");
df694daa
KY
12552 board_config = ALC262_BASIC;
12553 }
12554 }
12555
dc1eae25 12556 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12557 err = snd_hda_attach_beep_device(codec, 0x1);
12558 if (err < 0) {
12559 alc_free(codec);
12560 return err;
12561 }
680cd536
KK
12562 }
12563
df694daa 12564 if (board_config != ALC262_AUTO)
e9c364c0 12565 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12566
df694daa
KY
12567 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12568 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12569
df694daa
KY
12570 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12571 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12572
f12ab1e0 12573 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12574 int i;
12575 /* check whether the digital-mic has to be supported */
12576 for (i = 0; i < spec->input_mux->num_items; i++) {
12577 if (spec->input_mux->items[i].index >= 9)
12578 break;
12579 }
12580 if (i < spec->input_mux->num_items) {
12581 /* use only ADC0 */
12582 spec->adc_nids = alc262_dmic_adc_nids;
12583 spec->num_adc_nids = 1;
12584 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12585 } else {
8c927b4a
TI
12586 /* all analog inputs */
12587 /* check whether NID 0x07 is valid */
12588 unsigned int wcap = get_wcaps(codec, 0x07);
12589
12590 /* get type */
a22d543a 12591 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12592 if (wcap != AC_WID_AUD_IN) {
12593 spec->adc_nids = alc262_adc_nids_alt;
12594 spec->num_adc_nids =
12595 ARRAY_SIZE(alc262_adc_nids_alt);
12596 spec->capsrc_nids = alc262_capsrc_nids_alt;
12597 } else {
12598 spec->adc_nids = alc262_adc_nids;
12599 spec->num_adc_nids =
12600 ARRAY_SIZE(alc262_adc_nids);
12601 spec->capsrc_nids = alc262_capsrc_nids;
12602 }
df694daa
KY
12603 }
12604 }
e64f14f4 12605 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12606 set_capture_mixer(codec);
dc1eae25 12607 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12608 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12609
2134ea4f
TI
12610 spec->vmaster_nid = 0x0c;
12611
df694daa
KY
12612 codec->patch_ops = alc_patch_ops;
12613 if (board_config == ALC262_AUTO)
ae6b813a 12614 spec->init_hook = alc262_auto_init;
cb53c626
TI
12615#ifdef CONFIG_SND_HDA_POWER_SAVE
12616 if (!spec->loopback.amplist)
12617 spec->loopback.amplist = alc262_loopbacks;
12618#endif
ea1fb29a 12619
df694daa
KY
12620 return 0;
12621}
12622
a361d84b
KY
12623/*
12624 * ALC268 channel source setting (2 channel)
12625 */
12626#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12627#define alc268_modes alc260_modes
ea1fb29a 12628
a361d84b
KY
12629static hda_nid_t alc268_dac_nids[2] = {
12630 /* front, hp */
12631 0x02, 0x03
12632};
12633
12634static hda_nid_t alc268_adc_nids[2] = {
12635 /* ADC0-1 */
12636 0x08, 0x07
12637};
12638
12639static hda_nid_t alc268_adc_nids_alt[1] = {
12640 /* ADC0 */
12641 0x08
12642};
12643
e1406348
TI
12644static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12645
a361d84b
KY
12646static struct snd_kcontrol_new alc268_base_mixer[] = {
12647 /* output mixer control */
12648 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12649 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12650 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12652 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12653 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12654 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12655 { }
12656};
12657
42171c17
TI
12658static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12659 /* output mixer control */
12660 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12661 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12662 ALC262_HIPPO_MASTER_SWITCH,
12663 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12664 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12665 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12666 { }
12667};
12668
aef9d318
TI
12669/* bind Beep switches of both NID 0x0f and 0x10 */
12670static struct hda_bind_ctls alc268_bind_beep_sw = {
12671 .ops = &snd_hda_bind_sw,
12672 .values = {
12673 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12674 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12675 0
12676 },
12677};
12678
12679static struct snd_kcontrol_new alc268_beep_mixer[] = {
12680 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12681 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12682 { }
12683};
12684
d1a991a6
KY
12685static struct hda_verb alc268_eapd_verbs[] = {
12686 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12687 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12688 { }
12689};
12690
d273809e 12691/* Toshiba specific */
d273809e
TI
12692static struct hda_verb alc268_toshiba_verbs[] = {
12693 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12694 { } /* end */
12695};
12696
12697/* Acer specific */
889c4395 12698/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12699static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12700 .ops = &snd_hda_bind_vol,
12701 .values = {
12702 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12703 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12704 0
12705 },
12706};
12707
889c4395
TI
12708/* mute/unmute internal speaker according to the hp jack and mute state */
12709static void alc268_acer_automute(struct hda_codec *codec, int force)
12710{
12711 struct alc_spec *spec = codec->spec;
12712 unsigned int mute;
12713
12714 if (force || !spec->sense_updated) {
864f92be 12715 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12716 spec->sense_updated = 1;
12717 }
12718 if (spec->jack_present)
12719 mute = HDA_AMP_MUTE; /* mute internal speaker */
12720 else /* unmute internal speaker if necessary */
12721 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12722 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12723 HDA_AMP_MUTE, mute);
12724}
12725
12726
12727/* bind hp and internal speaker mute (with plug check) */
12728static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12729 struct snd_ctl_elem_value *ucontrol)
12730{
12731 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12732 long *valp = ucontrol->value.integer.value;
12733 int change;
12734
8de56b7d 12735 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12736 if (change)
12737 alc268_acer_automute(codec, 0);
12738 return change;
12739}
d273809e 12740
8ef355da
KY
12741static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12742 /* output mixer control */
12743 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12744 {
12745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12746 .name = "Master Playback Switch",
5e26dfd0 12747 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12748 .info = snd_hda_mixer_amp_switch_info,
12749 .get = snd_hda_mixer_amp_switch_get,
12750 .put = alc268_acer_master_sw_put,
12751 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12752 },
12753 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12754 { }
12755};
12756
d273809e
TI
12757static struct snd_kcontrol_new alc268_acer_mixer[] = {
12758 /* output mixer control */
12759 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12760 {
12761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12762 .name = "Master Playback Switch",
5e26dfd0 12763 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12764 .info = snd_hda_mixer_amp_switch_info,
12765 .get = snd_hda_mixer_amp_switch_get,
12766 .put = alc268_acer_master_sw_put,
12767 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12768 },
33bf17ab
TI
12769 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12770 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12771 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12772 { }
12773};
12774
c238b4f4
TI
12775static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12776 /* output mixer control */
12777 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12778 {
12779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12780 .name = "Master Playback Switch",
5e26dfd0 12781 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12782 .info = snd_hda_mixer_amp_switch_info,
12783 .get = snd_hda_mixer_amp_switch_get,
12784 .put = alc268_acer_master_sw_put,
12785 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12786 },
12787 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12788 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12789 { }
12790};
12791
8ef355da
KY
12792static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12793 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12794 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12797 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12798 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12799 { }
12800};
12801
d273809e 12802static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12803 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12804 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12805 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12807 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12808 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12809 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12810 { }
12811};
12812
12813/* unsolicited event for HP jack sensing */
42171c17 12814#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12815#define alc268_toshiba_setup alc262_hippo_setup
12816#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12817
12818static void alc268_acer_unsol_event(struct hda_codec *codec,
12819 unsigned int res)
12820{
889c4395 12821 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12822 return;
12823 alc268_acer_automute(codec, 1);
12824}
12825
889c4395
TI
12826static void alc268_acer_init_hook(struct hda_codec *codec)
12827{
12828 alc268_acer_automute(codec, 1);
12829}
12830
8ef355da
KY
12831/* toggle speaker-output according to the hp-jack state */
12832static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12833{
12834 unsigned int present;
12835 unsigned char bits;
12836
864f92be 12837 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12838 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12839 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12840 HDA_AMP_MUTE, bits);
8ef355da 12841 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12842 HDA_AMP_MUTE, bits);
8ef355da
KY
12843}
12844
8ef355da
KY
12845static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12846 unsigned int res)
12847{
4f5d1706
TI
12848 switch (res >> 26) {
12849 case ALC880_HP_EVENT:
8ef355da 12850 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12851 break;
12852 case ALC880_MIC_EVENT:
12853 alc_mic_automute(codec);
12854 break;
12855 }
12856}
12857
12858static void alc268_acer_lc_setup(struct hda_codec *codec)
12859{
12860 struct alc_spec *spec = codec->spec;
12861 spec->ext_mic.pin = 0x18;
12862 spec->ext_mic.mux_idx = 0;
12863 spec->int_mic.pin = 0x12;
12864 spec->int_mic.mux_idx = 6;
12865 spec->auto_mic = 1;
8ef355da
KY
12866}
12867
12868static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12869{
12870 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12871 alc_mic_automute(codec);
8ef355da
KY
12872}
12873
3866f0b0
TI
12874static struct snd_kcontrol_new alc268_dell_mixer[] = {
12875 /* output mixer control */
12876 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12877 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12878 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12880 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12881 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12882 { }
12883};
12884
12885static struct hda_verb alc268_dell_verbs[] = {
12886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12887 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12888 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12890 { }
12891};
12892
12893/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12894static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12895{
a9fd4f3f 12896 struct alc_spec *spec = codec->spec;
3866f0b0 12897
a9fd4f3f
TI
12898 spec->autocfg.hp_pins[0] = 0x15;
12899 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12900 spec->ext_mic.pin = 0x18;
12901 spec->ext_mic.mux_idx = 0;
12902 spec->int_mic.pin = 0x19;
12903 spec->int_mic.mux_idx = 1;
12904 spec->auto_mic = 1;
3866f0b0
TI
12905}
12906
eb5a6621
HRK
12907static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12908 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12909 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12910 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12913 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12914 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12915 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12916 { }
12917};
12918
12919static struct hda_verb alc267_quanta_il1_verbs[] = {
12920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12921 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12922 { }
12923};
12924
4f5d1706 12925static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12926{
a9fd4f3f 12927 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12928 spec->autocfg.hp_pins[0] = 0x15;
12929 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12930 spec->ext_mic.pin = 0x18;
12931 spec->ext_mic.mux_idx = 0;
12932 spec->int_mic.pin = 0x19;
12933 spec->int_mic.mux_idx = 1;
12934 spec->auto_mic = 1;
eb5a6621
HRK
12935}
12936
a361d84b
KY
12937/*
12938 * generic initialization of ADC, input mixers and output mixers
12939 */
12940static struct hda_verb alc268_base_init_verbs[] = {
12941 /* Unmute DAC0-1 and set vol = 0 */
12942 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12943 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12944
12945 /*
12946 * Set up output mixers (0x0c - 0x0e)
12947 */
12948 /* set vol=0 to output mixers */
12949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12950 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12951
12952 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12953 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12954
12955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12957 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12958 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12959 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12960 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12961 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12962 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12963
12964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12966 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12967 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12968 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12969
12970 /* set PCBEEP vol = 0, mute connections */
12971 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12972 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12973 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12974
a9b3aa8a 12975 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12976
a9b3aa8a
JZ
12977 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12978 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12979 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12980 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 12981
a361d84b
KY
12982 { }
12983};
12984
12985/*
12986 * generic initialization of ADC, input mixers and output mixers
12987 */
12988static struct hda_verb alc268_volume_init_verbs[] = {
12989 /* set output DAC */
4cfb91c6
TI
12990 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12991 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12992
12993 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12994 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12995 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12996 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12997 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12998
a361d84b 12999 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13001 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13002
13003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13004 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13005
aef9d318
TI
13006 /* set PCBEEP vol = 0, mute connections */
13007 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13009 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13010
13011 { }
13012};
13013
fdbc6626
TI
13014static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13015 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13016 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13017 { } /* end */
13018};
13019
a361d84b
KY
13020static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13021 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13022 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13023 _DEFINE_CAPSRC(1),
a361d84b
KY
13024 { } /* end */
13025};
13026
13027static struct snd_kcontrol_new alc268_capture_mixer[] = {
13028 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13029 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13030 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13031 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13032 _DEFINE_CAPSRC(2),
a361d84b
KY
13033 { } /* end */
13034};
13035
13036static struct hda_input_mux alc268_capture_source = {
13037 .num_items = 4,
13038 .items = {
13039 { "Mic", 0x0 },
13040 { "Front Mic", 0x1 },
13041 { "Line", 0x2 },
13042 { "CD", 0x3 },
13043 },
13044};
13045
0ccb541c 13046static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13047 .num_items = 3,
13048 .items = {
13049 { "Mic", 0x0 },
13050 { "Internal Mic", 0x1 },
13051 { "Line", 0x2 },
13052 },
13053};
13054
13055static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13056 .num_items = 3,
13057 .items = {
13058 { "Mic", 0x0 },
13059 { "Internal Mic", 0x6 },
13060 { "Line", 0x2 },
13061 },
13062};
13063
86c53bd2
JW
13064#ifdef CONFIG_SND_DEBUG
13065static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13066 /* Volume widgets */
13067 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13068 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13069 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13070 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13071 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13072 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13073 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13074 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13075 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13076 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13077 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13078 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13079 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13080 /* The below appears problematic on some hardwares */
13081 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13082 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13083 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13084 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13085 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13086
13087 /* Modes for retasking pin widgets */
13088 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13089 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13090 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13091 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13092
13093 /* Controls for GPIO pins, assuming they are configured as outputs */
13094 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13095 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13096 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13097 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13098
13099 /* Switches to allow the digital SPDIF output pin to be enabled.
13100 * The ALC268 does not have an SPDIF input.
13101 */
13102 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13103
13104 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13105 * this output to turn on an external amplifier.
13106 */
13107 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13108 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13109
13110 { } /* end */
13111};
13112#endif
13113
a361d84b
KY
13114/* create input playback/capture controls for the given pin */
13115static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13116 const char *ctlname, int idx)
13117{
3f3b7c1a 13118 hda_nid_t dac;
a361d84b
KY
13119 int err;
13120
3f3b7c1a
TI
13121 switch (nid) {
13122 case 0x14:
13123 case 0x16:
13124 dac = 0x02;
13125 break;
13126 case 0x15:
531d8791 13127 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13128 dac = 0x03;
13129 break;
13130 default:
13131 return 0;
13132 }
13133 if (spec->multiout.dac_nids[0] != dac &&
13134 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13135 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13136 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13137 HDA_OUTPUT));
13138 if (err < 0)
13139 return err;
3f3b7c1a
TI
13140 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13141 }
13142
3f3b7c1a 13143 if (nid != 0x16)
0afe5f89 13144 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13145 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13146 else /* mono */
0afe5f89 13147 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13148 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13149 if (err < 0)
13150 return err;
13151 return 0;
13152}
13153
13154/* add playback controls from the parsed DAC table */
13155static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13156 const struct auto_pin_cfg *cfg)
13157{
13158 hda_nid_t nid;
13159 int err;
13160
a361d84b 13161 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13162
13163 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13164 if (nid) {
13165 const char *name;
13166 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13167 name = "Speaker";
13168 else
13169 name = "Front";
13170 err = alc268_new_analog_output(spec, nid, name, 0);
13171 if (err < 0)
13172 return err;
13173 }
a361d84b
KY
13174
13175 nid = cfg->speaker_pins[0];
13176 if (nid == 0x1d) {
0afe5f89 13177 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13178 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13179 if (err < 0)
13180 return err;
3f3b7c1a
TI
13181 } else {
13182 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13183 if (err < 0)
13184 return err;
a361d84b
KY
13185 }
13186 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13187 if (nid) {
13188 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13189 if (err < 0)
13190 return err;
13191 }
a361d84b
KY
13192
13193 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13194 if (nid == 0x16) {
0afe5f89 13195 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13196 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13197 if (err < 0)
13198 return err;
13199 }
ea1fb29a 13200 return 0;
a361d84b
KY
13201}
13202
13203/* create playback/capture controls for input pins */
05f5f477 13204static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13205 const struct auto_pin_cfg *cfg)
13206{
05f5f477 13207 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13208}
13209
e9af4f36
TI
13210static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13211 hda_nid_t nid, int pin_type)
13212{
13213 int idx;
13214
13215 alc_set_pin_output(codec, nid, pin_type);
13216 if (nid == 0x14 || nid == 0x16)
13217 idx = 0;
13218 else
13219 idx = 1;
13220 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13221}
13222
13223static void alc268_auto_init_multi_out(struct hda_codec *codec)
13224{
13225 struct alc_spec *spec = codec->spec;
13226 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13227 if (nid) {
13228 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13229 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13230 }
13231}
13232
13233static void alc268_auto_init_hp_out(struct hda_codec *codec)
13234{
13235 struct alc_spec *spec = codec->spec;
13236 hda_nid_t pin;
13237
13238 pin = spec->autocfg.hp_pins[0];
13239 if (pin)
13240 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13241 pin = spec->autocfg.speaker_pins[0];
13242 if (pin)
13243 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13244}
13245
a361d84b
KY
13246static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13247{
13248 struct alc_spec *spec = codec->spec;
13249 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13250 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13251 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13252 unsigned int dac_vol1, dac_vol2;
13253
e9af4f36 13254 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13255 snd_hda_codec_write(codec, speaker_nid, 0,
13256 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13257 /* mute mixer inputs from 0x1d */
a361d84b
KY
13258 snd_hda_codec_write(codec, 0x0f, 0,
13259 AC_VERB_SET_AMP_GAIN_MUTE,
13260 AMP_IN_UNMUTE(1));
13261 snd_hda_codec_write(codec, 0x10, 0,
13262 AC_VERB_SET_AMP_GAIN_MUTE,
13263 AMP_IN_UNMUTE(1));
13264 } else {
e9af4f36 13265 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13266 snd_hda_codec_write(codec, 0x0f, 0,
13267 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13268 snd_hda_codec_write(codec, 0x10, 0,
13269 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13270 }
13271
13272 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13273 if (line_nid == 0x14)
a361d84b
KY
13274 dac_vol2 = AMP_OUT_ZERO;
13275 else if (line_nid == 0x15)
13276 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13277 if (hp_nid == 0x14)
a361d84b
KY
13278 dac_vol2 = AMP_OUT_ZERO;
13279 else if (hp_nid == 0x15)
13280 dac_vol1 = AMP_OUT_ZERO;
13281 if (line_nid != 0x16 || hp_nid != 0x16 ||
13282 spec->autocfg.line_out_pins[1] != 0x16 ||
13283 spec->autocfg.line_out_pins[2] != 0x16)
13284 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13285
13286 snd_hda_codec_write(codec, 0x02, 0,
13287 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13288 snd_hda_codec_write(codec, 0x03, 0,
13289 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13290}
13291
def319f9 13292/* pcm configuration: identical with ALC880 */
a361d84b
KY
13293#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13294#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13295#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13296#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13297
13298/*
13299 * BIOS auto configuration
13300 */
13301static int alc268_parse_auto_config(struct hda_codec *codec)
13302{
13303 struct alc_spec *spec = codec->spec;
13304 int err;
13305 static hda_nid_t alc268_ignore[] = { 0 };
13306
13307 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13308 alc268_ignore);
13309 if (err < 0)
13310 return err;
7e0e44d4
TI
13311 if (!spec->autocfg.line_outs) {
13312 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13313 spec->multiout.max_channels = 2;
13314 spec->no_analog = 1;
13315 goto dig_only;
13316 }
a361d84b 13317 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13318 }
a361d84b
KY
13319 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13320 if (err < 0)
13321 return err;
05f5f477 13322 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13323 if (err < 0)
13324 return err;
13325
13326 spec->multiout.max_channels = 2;
13327
7e0e44d4 13328 dig_only:
a361d84b 13329 /* digital only support output */
7e0e44d4 13330 if (spec->autocfg.dig_outs) {
a361d84b 13331 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
13332 spec->dig_out_type = spec->autocfg.dig_out_type[0];
13333 }
603c4019 13334 if (spec->kctls.list)
d88897ea 13335 add_mixer(spec, spec->kctls.list);
a361d84b 13336
892981ff 13337 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13338 add_mixer(spec, alc268_beep_mixer);
aef9d318 13339
d88897ea 13340 add_verb(spec, alc268_volume_init_verbs);
5908589f 13341 spec->num_mux_defs = 2;
61b9b9b1 13342 spec->input_mux = &spec->private_imux[0];
a361d84b 13343
776e184e
TI
13344 err = alc_auto_add_mic_boost(codec);
13345 if (err < 0)
13346 return err;
13347
6227cdce 13348 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13349
a361d84b
KY
13350 return 1;
13351}
13352
a361d84b
KY
13353#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13354
13355/* init callback for auto-configuration model -- overriding the default init */
13356static void alc268_auto_init(struct hda_codec *codec)
13357{
f6c7e546 13358 struct alc_spec *spec = codec->spec;
a361d84b
KY
13359 alc268_auto_init_multi_out(codec);
13360 alc268_auto_init_hp_out(codec);
13361 alc268_auto_init_mono_speaker_out(codec);
13362 alc268_auto_init_analog_input(codec);
f6c7e546 13363 if (spec->unsol_event)
7fb0d78f 13364 alc_inithook(codec);
a361d84b
KY
13365}
13366
13367/*
13368 * configuration and preset
13369 */
13370static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13371 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13372 [ALC268_3ST] = "3stack",
983f8ae4 13373 [ALC268_TOSHIBA] = "toshiba",
d273809e 13374 [ALC268_ACER] = "acer",
c238b4f4 13375 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13376 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13377 [ALC268_DELL] = "dell",
f12462c5 13378 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13379#ifdef CONFIG_SND_DEBUG
13380 [ALC268_TEST] = "test",
13381#endif
a361d84b
KY
13382 [ALC268_AUTO] = "auto",
13383};
13384
13385static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13386 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13387 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13388 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13389 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13390 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13391 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13392 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13393 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13394 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13395 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13396 /* almost compatible with toshiba but with optional digital outs;
13397 * auto-probing seems working fine
13398 */
8871e5b9 13399 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13400 ALC268_AUTO),
a361d84b 13401 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13402 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13403 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13404 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13405 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13406 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13407 {}
13408};
13409
3abf2f36
TI
13410/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13411static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13412 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13413 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13414 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13415 ALC268_TOSHIBA),
13416 {}
13417};
13418
a361d84b 13419static struct alc_config_preset alc268_presets[] = {
eb5a6621 13420 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13421 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13422 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13423 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13424 alc267_quanta_il1_verbs },
13425 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13426 .dac_nids = alc268_dac_nids,
13427 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13428 .adc_nids = alc268_adc_nids_alt,
13429 .hp_nid = 0x03,
13430 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13431 .channel_mode = alc268_modes,
4f5d1706
TI
13432 .unsol_event = alc_sku_unsol_event,
13433 .setup = alc267_quanta_il1_setup,
13434 .init_hook = alc_inithook,
eb5a6621 13435 },
a361d84b 13436 [ALC268_3ST] = {
aef9d318
TI
13437 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13438 alc268_beep_mixer },
a361d84b
KY
13439 .init_verbs = { alc268_base_init_verbs },
13440 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13441 .dac_nids = alc268_dac_nids,
13442 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13443 .adc_nids = alc268_adc_nids_alt,
e1406348 13444 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13445 .hp_nid = 0x03,
13446 .dig_out_nid = ALC268_DIGOUT_NID,
13447 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13448 .channel_mode = alc268_modes,
13449 .input_mux = &alc268_capture_source,
13450 },
d1a991a6 13451 [ALC268_TOSHIBA] = {
42171c17 13452 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13453 alc268_beep_mixer },
d273809e
TI
13454 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13455 alc268_toshiba_verbs },
d1a991a6
KY
13456 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13457 .dac_nids = alc268_dac_nids,
13458 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13459 .adc_nids = alc268_adc_nids_alt,
e1406348 13460 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13461 .hp_nid = 0x03,
13462 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13463 .channel_mode = alc268_modes,
13464 .input_mux = &alc268_capture_source,
d273809e 13465 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13466 .setup = alc268_toshiba_setup,
13467 .init_hook = alc268_toshiba_automute,
d273809e
TI
13468 },
13469 [ALC268_ACER] = {
432fd133 13470 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13471 alc268_beep_mixer },
d273809e
TI
13472 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13473 alc268_acer_verbs },
13474 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13475 .dac_nids = alc268_dac_nids,
13476 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13477 .adc_nids = alc268_adc_nids_alt,
e1406348 13478 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13479 .hp_nid = 0x02,
13480 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13481 .channel_mode = alc268_modes,
0ccb541c 13482 .input_mux = &alc268_acer_capture_source,
d273809e 13483 .unsol_event = alc268_acer_unsol_event,
889c4395 13484 .init_hook = alc268_acer_init_hook,
d1a991a6 13485 },
c238b4f4
TI
13486 [ALC268_ACER_DMIC] = {
13487 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13488 alc268_beep_mixer },
13489 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13490 alc268_acer_verbs },
13491 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13492 .dac_nids = alc268_dac_nids,
13493 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13494 .adc_nids = alc268_adc_nids_alt,
13495 .capsrc_nids = alc268_capsrc_nids,
13496 .hp_nid = 0x02,
13497 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13498 .channel_mode = alc268_modes,
13499 .input_mux = &alc268_acer_dmic_capture_source,
13500 .unsol_event = alc268_acer_unsol_event,
13501 .init_hook = alc268_acer_init_hook,
13502 },
8ef355da
KY
13503 [ALC268_ACER_ASPIRE_ONE] = {
13504 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13505 alc268_beep_mixer,
fdbc6626 13506 alc268_capture_nosrc_mixer },
8ef355da
KY
13507 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13508 alc268_acer_aspire_one_verbs },
13509 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13510 .dac_nids = alc268_dac_nids,
13511 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13512 .adc_nids = alc268_adc_nids_alt,
13513 .capsrc_nids = alc268_capsrc_nids,
13514 .hp_nid = 0x03,
13515 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13516 .channel_mode = alc268_modes,
8ef355da 13517 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13518 .setup = alc268_acer_lc_setup,
8ef355da
KY
13519 .init_hook = alc268_acer_lc_init_hook,
13520 },
3866f0b0 13521 [ALC268_DELL] = {
fdbc6626
TI
13522 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13523 alc268_capture_nosrc_mixer },
3866f0b0
TI
13524 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13525 alc268_dell_verbs },
13526 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13527 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13528 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13529 .adc_nids = alc268_adc_nids_alt,
13530 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13531 .hp_nid = 0x02,
13532 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13533 .channel_mode = alc268_modes,
a9fd4f3f 13534 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13535 .setup = alc268_dell_setup,
13536 .init_hook = alc_inithook,
3866f0b0 13537 },
f12462c5 13538 [ALC268_ZEPTO] = {
aef9d318
TI
13539 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13540 alc268_beep_mixer },
f12462c5
MT
13541 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13542 alc268_toshiba_verbs },
13543 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13544 .dac_nids = alc268_dac_nids,
13545 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13546 .adc_nids = alc268_adc_nids_alt,
e1406348 13547 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13548 .hp_nid = 0x03,
13549 .dig_out_nid = ALC268_DIGOUT_NID,
13550 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13551 .channel_mode = alc268_modes,
13552 .input_mux = &alc268_capture_source,
4f5d1706
TI
13553 .setup = alc268_toshiba_setup,
13554 .init_hook = alc268_toshiba_automute,
f12462c5 13555 },
86c53bd2
JW
13556#ifdef CONFIG_SND_DEBUG
13557 [ALC268_TEST] = {
13558 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13559 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13560 alc268_volume_init_verbs },
13561 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13562 .dac_nids = alc268_dac_nids,
13563 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13564 .adc_nids = alc268_adc_nids_alt,
e1406348 13565 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13566 .hp_nid = 0x03,
13567 .dig_out_nid = ALC268_DIGOUT_NID,
13568 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13569 .channel_mode = alc268_modes,
13570 .input_mux = &alc268_capture_source,
13571 },
13572#endif
a361d84b
KY
13573};
13574
13575static int patch_alc268(struct hda_codec *codec)
13576{
13577 struct alc_spec *spec;
13578 int board_config;
22971e3a 13579 int i, has_beep, err;
a361d84b 13580
ef86f581 13581 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13582 if (spec == NULL)
13583 return -ENOMEM;
13584
13585 codec->spec = spec;
13586
13587 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13588 alc268_models,
13589 alc268_cfg_tbl);
13590
3abf2f36
TI
13591 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13592 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13593 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13594
a361d84b 13595 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13596 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13597 codec->chip_name);
a361d84b
KY
13598 board_config = ALC268_AUTO;
13599 }
13600
13601 if (board_config == ALC268_AUTO) {
13602 /* automatic parse from the BIOS config */
13603 err = alc268_parse_auto_config(codec);
13604 if (err < 0) {
13605 alc_free(codec);
13606 return err;
13607 } else if (!err) {
13608 printk(KERN_INFO
13609 "hda_codec: Cannot set up configuration "
13610 "from BIOS. Using base mode...\n");
13611 board_config = ALC268_3ST;
13612 }
13613 }
13614
13615 if (board_config != ALC268_AUTO)
e9c364c0 13616 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13617
a361d84b
KY
13618 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13619 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13620 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13621
a361d84b
KY
13622 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13623
22971e3a
TI
13624 has_beep = 0;
13625 for (i = 0; i < spec->num_mixers; i++) {
13626 if (spec->mixers[i] == alc268_beep_mixer) {
13627 has_beep = 1;
13628 break;
13629 }
13630 }
13631
13632 if (has_beep) {
13633 err = snd_hda_attach_beep_device(codec, 0x1);
13634 if (err < 0) {
13635 alc_free(codec);
13636 return err;
13637 }
13638 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13639 /* override the amp caps for beep generator */
13640 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13641 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13642 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13643 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13644 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13645 }
aef9d318 13646
7e0e44d4 13647 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13648 /* check whether NID 0x07 is valid */
13649 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13650 int i;
3866f0b0 13651
defb5ab2 13652 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13653 /* get type */
a22d543a 13654 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13655 if (spec->auto_mic ||
13656 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13657 spec->adc_nids = alc268_adc_nids_alt;
13658 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13659 if (spec->auto_mic)
13660 fixup_automic_adc(codec);
fdbc6626
TI
13661 if (spec->auto_mic || spec->input_mux->num_items == 1)
13662 add_mixer(spec, alc268_capture_nosrc_mixer);
13663 else
13664 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13665 } else {
13666 spec->adc_nids = alc268_adc_nids;
13667 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13668 add_mixer(spec, alc268_capture_mixer);
a361d84b 13669 }
85860c06
TI
13670 /* set default input source */
13671 for (i = 0; i < spec->num_adc_nids; i++)
13672 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13673 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13674 i < spec->num_mux_defs ?
13675 spec->input_mux[i].items[0].index :
85860c06 13676 spec->input_mux->items[0].index);
a361d84b 13677 }
2134ea4f
TI
13678
13679 spec->vmaster_nid = 0x02;
13680
a361d84b
KY
13681 codec->patch_ops = alc_patch_ops;
13682 if (board_config == ALC268_AUTO)
13683 spec->init_hook = alc268_auto_init;
ea1fb29a 13684
a361d84b
KY
13685 return 0;
13686}
13687
f6a92248
KY
13688/*
13689 * ALC269 channel source setting (2 channel)
13690 */
13691#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13692
13693#define alc269_dac_nids alc260_dac_nids
13694
13695static hda_nid_t alc269_adc_nids[1] = {
13696 /* ADC1 */
f53281e6
KY
13697 0x08,
13698};
13699
e01bf509
TI
13700static hda_nid_t alc269_capsrc_nids[1] = {
13701 0x23,
13702};
13703
84898e87
KY
13704static hda_nid_t alc269vb_adc_nids[1] = {
13705 /* ADC1 */
13706 0x09,
13707};
13708
13709static hda_nid_t alc269vb_capsrc_nids[1] = {
13710 0x22,
13711};
13712
6694635d
TI
13713static hda_nid_t alc269_adc_candidates[] = {
13714 0x08, 0x09, 0x07,
13715};
e01bf509 13716
f6a92248
KY
13717#define alc269_modes alc260_modes
13718#define alc269_capture_source alc880_lg_lw_capture_source
13719
13720static struct snd_kcontrol_new alc269_base_mixer[] = {
13721 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13722 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13723 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13724 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13730 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13731 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13732 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13733 { } /* end */
13734};
13735
60db6b53
KY
13736static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13737 /* output mixer control */
13738 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13739 {
13740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13741 .name = "Master Playback Switch",
5e26dfd0 13742 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13743 .info = snd_hda_mixer_amp_switch_info,
13744 .get = snd_hda_mixer_amp_switch_get,
13745 .put = alc268_acer_master_sw_put,
13746 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13747 },
13748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13750 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13751 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13752 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13753 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13754 { }
13755};
13756
64154835
TV
13757static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13758 /* output mixer control */
13759 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13760 {
13761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13762 .name = "Master Playback Switch",
5e26dfd0 13763 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13764 .info = snd_hda_mixer_amp_switch_info,
13765 .get = snd_hda_mixer_amp_switch_get,
13766 .put = alc268_acer_master_sw_put,
13767 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13768 },
13769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13771 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13773 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13774 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13775 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13776 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13777 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13778 { }
13779};
13780
84898e87 13781static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13782 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13783 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13785 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13786 { } /* end */
13787};
13788
84898e87
KY
13789static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13790 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13791 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13793 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13794 { } /* end */
13795};
13796
f53281e6 13797/* capture mixer elements */
84898e87
KY
13798static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13799 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13800 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13802 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13803 { } /* end */
13804};
13805
13806static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13807 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13808 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13809 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13810 { } /* end */
13811};
13812
84898e87
KY
13813static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13814 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13815 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13816 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13817 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13818 { } /* end */
13819};
13820
13821static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13822 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13823 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13825 { } /* end */
13826};
13827
26f5df26 13828/* FSC amilo */
84898e87 13829#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13830
60db6b53
KY
13831static struct hda_verb alc269_quanta_fl1_verbs[] = {
13832 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13833 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13835 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13836 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13837 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13838 { }
13839};
f6a92248 13840
64154835
TV
13841static struct hda_verb alc269_lifebook_verbs[] = {
13842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13843 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13844 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13846 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13847 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13848 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13849 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13850 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13851 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13852 { }
13853};
13854
60db6b53
KY
13855/* toggle speaker-output according to the hp-jack state */
13856static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13857{
13858 unsigned int present;
13859 unsigned char bits;
f6a92248 13860
864f92be 13861 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13862 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13863 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13864 HDA_AMP_MUTE, bits);
60db6b53 13865 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13866 HDA_AMP_MUTE, bits);
f6a92248 13867
60db6b53
KY
13868 snd_hda_codec_write(codec, 0x20, 0,
13869 AC_VERB_SET_COEF_INDEX, 0x0c);
13870 snd_hda_codec_write(codec, 0x20, 0,
13871 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13872
60db6b53
KY
13873 snd_hda_codec_write(codec, 0x20, 0,
13874 AC_VERB_SET_COEF_INDEX, 0x0c);
13875 snd_hda_codec_write(codec, 0x20, 0,
13876 AC_VERB_SET_PROC_COEF, 0x480);
13877}
f6a92248 13878
64154835
TV
13879/* toggle speaker-output according to the hp-jacks state */
13880static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13881{
13882 unsigned int present;
13883 unsigned char bits;
13884
13885 /* Check laptop headphone socket */
864f92be 13886 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13887
13888 /* Check port replicator headphone socket */
864f92be 13889 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13890
5dbd5ec6 13891 bits = present ? HDA_AMP_MUTE : 0;
64154835 13892 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13893 HDA_AMP_MUTE, bits);
64154835 13894 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13895 HDA_AMP_MUTE, bits);
64154835
TV
13896
13897 snd_hda_codec_write(codec, 0x20, 0,
13898 AC_VERB_SET_COEF_INDEX, 0x0c);
13899 snd_hda_codec_write(codec, 0x20, 0,
13900 AC_VERB_SET_PROC_COEF, 0x680);
13901
13902 snd_hda_codec_write(codec, 0x20, 0,
13903 AC_VERB_SET_COEF_INDEX, 0x0c);
13904 snd_hda_codec_write(codec, 0x20, 0,
13905 AC_VERB_SET_PROC_COEF, 0x480);
13906}
13907
64154835
TV
13908static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13909{
13910 unsigned int present_laptop;
13911 unsigned int present_dock;
13912
864f92be
WF
13913 present_laptop = snd_hda_jack_detect(codec, 0x18);
13914 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13915
13916 /* Laptop mic port overrides dock mic port, design decision */
13917 if (present_dock)
13918 snd_hda_codec_write(codec, 0x23, 0,
13919 AC_VERB_SET_CONNECT_SEL, 0x3);
13920 if (present_laptop)
13921 snd_hda_codec_write(codec, 0x23, 0,
13922 AC_VERB_SET_CONNECT_SEL, 0x0);
13923 if (!present_dock && !present_laptop)
13924 snd_hda_codec_write(codec, 0x23, 0,
13925 AC_VERB_SET_CONNECT_SEL, 0x1);
13926}
13927
60db6b53
KY
13928static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13929 unsigned int res)
13930{
4f5d1706
TI
13931 switch (res >> 26) {
13932 case ALC880_HP_EVENT:
60db6b53 13933 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13934 break;
13935 case ALC880_MIC_EVENT:
13936 alc_mic_automute(codec);
13937 break;
13938 }
60db6b53 13939}
f6a92248 13940
64154835
TV
13941static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13942 unsigned int res)
13943{
13944 if ((res >> 26) == ALC880_HP_EVENT)
13945 alc269_lifebook_speaker_automute(codec);
13946 if ((res >> 26) == ALC880_MIC_EVENT)
13947 alc269_lifebook_mic_autoswitch(codec);
13948}
13949
4f5d1706
TI
13950static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13951{
13952 struct alc_spec *spec = codec->spec;
20645d70
TI
13953 spec->autocfg.hp_pins[0] = 0x15;
13954 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13955 spec->ext_mic.pin = 0x18;
13956 spec->ext_mic.mux_idx = 0;
13957 spec->int_mic.pin = 0x19;
13958 spec->int_mic.mux_idx = 1;
13959 spec->auto_mic = 1;
13960}
13961
60db6b53
KY
13962static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13963{
13964 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13965 alc_mic_automute(codec);
60db6b53 13966}
f6a92248 13967
64154835
TV
13968static void alc269_lifebook_init_hook(struct hda_codec *codec)
13969{
13970 alc269_lifebook_speaker_automute(codec);
13971 alc269_lifebook_mic_autoswitch(codec);
13972}
13973
84898e87 13974static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
13975 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13976 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13977 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13978 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13979 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13980 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13981 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13982 {}
13983};
13984
84898e87 13985static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
13986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13987 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13988 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13989 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13990 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13991 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13992 {}
13993};
13994
84898e87
KY
13995static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13996 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13997 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13999 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14000 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14001 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14002 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14003 {}
14004};
14005
14006static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14007 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14008 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14009 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14011 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14012 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14013 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14014 {}
14015};
14016
f53281e6
KY
14017/* toggle speaker-output according to the hp-jack state */
14018static void alc269_speaker_automute(struct hda_codec *codec)
14019{
ebb83eeb
KY
14020 struct alc_spec *spec = codec->spec;
14021 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14022 unsigned int present;
60db6b53 14023 unsigned char bits;
f53281e6 14024
ebb83eeb 14025 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14026 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14027 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14028 HDA_AMP_MUTE, bits);
f53281e6 14029 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14030 HDA_AMP_MUTE, bits);
f53281e6
KY
14031}
14032
f53281e6 14033/* unsolicited event for HP jack sensing */
84898e87 14034static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14035 unsigned int res)
f53281e6 14036{
4f5d1706
TI
14037 switch (res >> 26) {
14038 case ALC880_HP_EVENT:
f53281e6 14039 alc269_speaker_automute(codec);
4f5d1706
TI
14040 break;
14041 case ALC880_MIC_EVENT:
14042 alc_mic_automute(codec);
14043 break;
14044 }
f53281e6
KY
14045}
14046
226b1ec8 14047static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14048{
4f5d1706 14049 struct alc_spec *spec = codec->spec;
20645d70
TI
14050 spec->autocfg.hp_pins[0] = 0x15;
14051 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14052 spec->ext_mic.pin = 0x18;
14053 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14054 spec->int_mic.pin = 0x19;
14055 spec->int_mic.mux_idx = 1;
4f5d1706 14056 spec->auto_mic = 1;
f53281e6
KY
14057}
14058
226b1ec8 14059static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14060{
14061 struct alc_spec *spec = codec->spec;
20645d70
TI
14062 spec->autocfg.hp_pins[0] = 0x15;
14063 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14064 spec->ext_mic.pin = 0x18;
14065 spec->ext_mic.mux_idx = 0;
14066 spec->int_mic.pin = 0x12;
226b1ec8 14067 spec->int_mic.mux_idx = 5;
84898e87
KY
14068 spec->auto_mic = 1;
14069}
14070
226b1ec8 14071static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14072{
4f5d1706 14073 struct alc_spec *spec = codec->spec;
226b1ec8 14074 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14075 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14076 spec->ext_mic.pin = 0x18;
14077 spec->ext_mic.mux_idx = 0;
14078 spec->int_mic.pin = 0x19;
14079 spec->int_mic.mux_idx = 1;
14080 spec->auto_mic = 1;
f53281e6
KY
14081}
14082
226b1ec8
KY
14083static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14084{
14085 struct alc_spec *spec = codec->spec;
14086 spec->autocfg.hp_pins[0] = 0x21;
14087 spec->autocfg.speaker_pins[0] = 0x14;
14088 spec->ext_mic.pin = 0x18;
14089 spec->ext_mic.mux_idx = 0;
14090 spec->int_mic.pin = 0x12;
14091 spec->int_mic.mux_idx = 6;
14092 spec->auto_mic = 1;
14093}
14094
84898e87 14095static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14096{
14097 alc269_speaker_automute(codec);
4f5d1706 14098 alc_mic_automute(codec);
f53281e6
KY
14099}
14100
60db6b53
KY
14101/*
14102 * generic initialization of ADC, input mixers and output mixers
14103 */
14104static struct hda_verb alc269_init_verbs[] = {
14105 /*
14106 * Unmute ADC0 and set the default input to mic-in
14107 */
84898e87 14108 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14109
14110 /*
84898e87 14111 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14112 */
14113 /* set vol=0 to output mixers */
14114 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14115 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14116
14117 /* set up input amps for analog loopback */
14118 /* Amp Indices: DAC = 0, mixer = 1 */
14119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14123 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14124 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14125
14126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14128 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14133
14134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14136
84898e87
KY
14137 /* FIXME: use Mux-type input source selection */
14138 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14139 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14140 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14141
84898e87
KY
14142 /* set EAPD */
14143 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14144 { }
14145};
14146
14147static struct hda_verb alc269vb_init_verbs[] = {
14148 /*
14149 * Unmute ADC0 and set the default input to mic-in
14150 */
14151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14152
14153 /*
14154 * Set up output mixers (0x02 - 0x03)
14155 */
14156 /* set vol=0 to output mixers */
14157 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14158 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14159
14160 /* set up input amps for analog loopback */
14161 /* Amp Indices: DAC = 0, mixer = 1 */
14162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14164 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14165 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14166 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14168
14169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14170 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14171 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14174 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14176
14177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14178 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14179
14180 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14181 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14182 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14183 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14184
14185 /* set EAPD */
14186 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14187 { }
14188};
14189
9d0b71b1
TI
14190#define alc269_auto_create_multi_out_ctls \
14191 alc268_auto_create_multi_out_ctls
05f5f477
TI
14192#define alc269_auto_create_input_ctls \
14193 alc268_auto_create_input_ctls
f6a92248
KY
14194
14195#ifdef CONFIG_SND_HDA_POWER_SAVE
14196#define alc269_loopbacks alc880_loopbacks
14197#endif
14198
def319f9 14199/* pcm configuration: identical with ALC880 */
f6a92248
KY
14200#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14201#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14202#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14203#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14204
f03d3115
TI
14205static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14206 .substreams = 1,
14207 .channels_min = 2,
14208 .channels_max = 8,
14209 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14210 /* NID is set in alc_build_pcms */
14211 .ops = {
14212 .open = alc880_playback_pcm_open,
14213 .prepare = alc880_playback_pcm_prepare,
14214 .cleanup = alc880_playback_pcm_cleanup
14215 },
14216};
14217
14218static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14219 .substreams = 1,
14220 .channels_min = 2,
14221 .channels_max = 2,
14222 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14223 /* NID is set in alc_build_pcms */
14224};
14225
ad35879a
TI
14226#ifdef CONFIG_SND_HDA_POWER_SAVE
14227static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14228{
14229 switch (codec->subsystem_id) {
14230 case 0x103c1586:
14231 return 1;
14232 }
14233 return 0;
14234}
14235
14236static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14237{
14238 /* update mute-LED according to the speaker mute state */
14239 if (nid == 0x01 || nid == 0x14) {
14240 int pinval;
14241 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14242 HDA_AMP_MUTE)
14243 pinval = 0x24;
14244 else
14245 pinval = 0x20;
14246 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14247 snd_hda_codec_update_cache(codec, 0x19, 0,
14248 AC_VERB_SET_PIN_WIDGET_CONTROL,
14249 pinval);
ad35879a
TI
14250 }
14251 return alc_check_power_status(codec, nid);
14252}
14253#endif /* CONFIG_SND_HDA_POWER_SAVE */
14254
840b64c0
TI
14255static int alc275_setup_dual_adc(struct hda_codec *codec)
14256{
14257 struct alc_spec *spec = codec->spec;
14258
14259 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14260 return 0;
14261 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14262 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14263 if (spec->ext_mic.pin <= 0x12) {
14264 spec->private_adc_nids[0] = 0x08;
14265 spec->private_adc_nids[1] = 0x11;
14266 spec->private_capsrc_nids[0] = 0x23;
14267 spec->private_capsrc_nids[1] = 0x22;
14268 } else {
14269 spec->private_adc_nids[0] = 0x11;
14270 spec->private_adc_nids[1] = 0x08;
14271 spec->private_capsrc_nids[0] = 0x22;
14272 spec->private_capsrc_nids[1] = 0x23;
14273 }
14274 spec->adc_nids = spec->private_adc_nids;
14275 spec->capsrc_nids = spec->private_capsrc_nids;
14276 spec->num_adc_nids = 2;
14277 spec->dual_adc_switch = 1;
14278 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14279 spec->adc_nids[0], spec->adc_nids[1]);
14280 return 1;
14281 }
14282 return 0;
14283}
14284
f6a92248
KY
14285/*
14286 * BIOS auto configuration
14287 */
14288static int alc269_parse_auto_config(struct hda_codec *codec)
14289{
14290 struct alc_spec *spec = codec->spec;
cfb9fb55 14291 int err;
f6a92248
KY
14292 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14293
14294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14295 alc269_ignore);
14296 if (err < 0)
14297 return err;
14298
14299 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14300 if (err < 0)
14301 return err;
05f5f477 14302 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14303 if (err < 0)
14304 return err;
14305
14306 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14307
0852d7a6 14308 if (spec->autocfg.dig_outs)
f6a92248
KY
14309 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
14310
603c4019 14311 if (spec->kctls.list)
d88897ea 14312 add_mixer(spec, spec->kctls.list);
f6a92248 14313
84898e87
KY
14314 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14315 add_verb(spec, alc269vb_init_verbs);
6227cdce 14316 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14317 } else {
14318 add_verb(spec, alc269_init_verbs);
6227cdce 14319 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14320 }
14321
f6a92248 14322 spec->num_mux_defs = 1;
61b9b9b1 14323 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14324
14325 if (!alc275_setup_dual_adc(codec))
14326 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14327 sizeof(alc269_adc_candidates));
6694635d 14328
e01bf509 14329 /* set default input source */
840b64c0
TI
14330 if (!spec->dual_adc_switch)
14331 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14332 0, AC_VERB_SET_CONNECT_SEL,
14333 spec->input_mux->items[0].index);
f6a92248
KY
14334
14335 err = alc_auto_add_mic_boost(codec);
14336 if (err < 0)
14337 return err;
14338
7e0e44d4 14339 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14340 set_capture_mixer(codec);
f53281e6 14341
f6a92248
KY
14342 return 1;
14343}
14344
e9af4f36
TI
14345#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14346#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14347#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14348
14349
14350/* init callback for auto-configuration model -- overriding the default init */
14351static void alc269_auto_init(struct hda_codec *codec)
14352{
f6c7e546 14353 struct alc_spec *spec = codec->spec;
f6a92248
KY
14354 alc269_auto_init_multi_out(codec);
14355 alc269_auto_init_hp_out(codec);
14356 alc269_auto_init_analog_input(codec);
f6c7e546 14357 if (spec->unsol_event)
7fb0d78f 14358 alc_inithook(codec);
f6a92248
KY
14359}
14360
ff818c24
TI
14361enum {
14362 ALC269_FIXUP_SONY_VAIO,
14363};
14364
fbc25669 14365static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
ff818c24
TI
14366 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14367 {}
14368};
14369
14370static const struct alc_fixup alc269_fixups[] = {
14371 [ALC269_FIXUP_SONY_VAIO] = {
14372 .verbs = alc269_sony_vaio_fixup_verbs
14373 },
14374};
14375
14376static struct snd_pci_quirk alc269_fixup_tbl[] = {
14377 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14378 {}
14379};
14380
14381
f6a92248
KY
14382/*
14383 * configuration and preset
14384 */
14385static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14386 [ALC269_BASIC] = "basic",
2922c9af 14387 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14388 [ALC269_AMIC] = "laptop-amic",
14389 [ALC269_DMIC] = "laptop-dmic",
64154835 14390 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14391 [ALC269_LIFEBOOK] = "lifebook",
14392 [ALC269_AUTO] = "auto",
f6a92248
KY
14393};
14394
14395static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14396 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14397 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14398 ALC269_AMIC),
14399 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14400 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14401 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14402 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14403 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14404 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14405 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14406 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14407 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14408 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14409 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14410 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14411 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14412 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14413 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14414 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14415 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14416 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14417 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14418 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14419 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14420 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14421 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14422 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14423 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14424 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14425 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14426 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14427 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14428 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14429 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14430 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14431 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14432 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14433 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14434 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14435 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14436 ALC269_DMIC),
60db6b53 14437 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14438 ALC269_DMIC),
14439 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14440 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14441 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14442 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14443 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14444 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14445 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14446 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14447 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14448 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14449 {}
14450};
14451
14452static struct alc_config_preset alc269_presets[] = {
14453 [ALC269_BASIC] = {
f9e336f6 14454 .mixers = { alc269_base_mixer },
f6a92248
KY
14455 .init_verbs = { alc269_init_verbs },
14456 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14457 .dac_nids = alc269_dac_nids,
14458 .hp_nid = 0x03,
14459 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14460 .channel_mode = alc269_modes,
14461 .input_mux = &alc269_capture_source,
14462 },
60db6b53
KY
14463 [ALC269_QUANTA_FL1] = {
14464 .mixers = { alc269_quanta_fl1_mixer },
14465 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14466 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14467 .dac_nids = alc269_dac_nids,
14468 .hp_nid = 0x03,
14469 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14470 .channel_mode = alc269_modes,
14471 .input_mux = &alc269_capture_source,
14472 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14473 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14474 .init_hook = alc269_quanta_fl1_init_hook,
14475 },
84898e87
KY
14476 [ALC269_AMIC] = {
14477 .mixers = { alc269_laptop_mixer },
14478 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14479 .init_verbs = { alc269_init_verbs,
84898e87 14480 alc269_laptop_amic_init_verbs },
f53281e6
KY
14481 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14482 .dac_nids = alc269_dac_nids,
14483 .hp_nid = 0x03,
14484 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14485 .channel_mode = alc269_modes,
84898e87
KY
14486 .unsol_event = alc269_laptop_unsol_event,
14487 .setup = alc269_laptop_amic_setup,
14488 .init_hook = alc269_laptop_inithook,
f53281e6 14489 },
84898e87
KY
14490 [ALC269_DMIC] = {
14491 .mixers = { alc269_laptop_mixer },
14492 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14493 .init_verbs = { alc269_init_verbs,
84898e87
KY
14494 alc269_laptop_dmic_init_verbs },
14495 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14496 .dac_nids = alc269_dac_nids,
14497 .hp_nid = 0x03,
14498 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14499 .channel_mode = alc269_modes,
14500 .unsol_event = alc269_laptop_unsol_event,
14501 .setup = alc269_laptop_dmic_setup,
14502 .init_hook = alc269_laptop_inithook,
14503 },
14504 [ALC269VB_AMIC] = {
14505 .mixers = { alc269vb_laptop_mixer },
14506 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14507 .init_verbs = { alc269vb_init_verbs,
14508 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14509 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14510 .dac_nids = alc269_dac_nids,
14511 .hp_nid = 0x03,
14512 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14513 .channel_mode = alc269_modes,
84898e87 14514 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14515 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14516 .init_hook = alc269_laptop_inithook,
14517 },
14518 [ALC269VB_DMIC] = {
14519 .mixers = { alc269vb_laptop_mixer },
14520 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14521 .init_verbs = { alc269vb_init_verbs,
14522 alc269vb_laptop_dmic_init_verbs },
14523 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14524 .dac_nids = alc269_dac_nids,
14525 .hp_nid = 0x03,
14526 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14527 .channel_mode = alc269_modes,
14528 .unsol_event = alc269_laptop_unsol_event,
14529 .setup = alc269vb_laptop_dmic_setup,
14530 .init_hook = alc269_laptop_inithook,
f53281e6 14531 },
26f5df26 14532 [ALC269_FUJITSU] = {
45bdd1c1 14533 .mixers = { alc269_fujitsu_mixer },
84898e87 14534 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14535 .init_verbs = { alc269_init_verbs,
84898e87 14536 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14537 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14538 .dac_nids = alc269_dac_nids,
14539 .hp_nid = 0x03,
14540 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14541 .channel_mode = alc269_modes,
84898e87
KY
14542 .unsol_event = alc269_laptop_unsol_event,
14543 .setup = alc269_laptop_dmic_setup,
14544 .init_hook = alc269_laptop_inithook,
26f5df26 14545 },
64154835
TV
14546 [ALC269_LIFEBOOK] = {
14547 .mixers = { alc269_lifebook_mixer },
14548 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14549 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14550 .dac_nids = alc269_dac_nids,
14551 .hp_nid = 0x03,
14552 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14553 .channel_mode = alc269_modes,
14554 .input_mux = &alc269_capture_source,
14555 .unsol_event = alc269_lifebook_unsol_event,
14556 .init_hook = alc269_lifebook_init_hook,
14557 },
f6a92248
KY
14558};
14559
14560static int patch_alc269(struct hda_codec *codec)
14561{
14562 struct alc_spec *spec;
14563 int board_config;
14564 int err;
84898e87 14565 int is_alc269vb = 0;
f6a92248
KY
14566
14567 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14568 if (spec == NULL)
14569 return -ENOMEM;
14570
14571 codec->spec = spec;
14572
da00c244
KY
14573 alc_auto_parse_customize_define(codec);
14574
274693f3 14575 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14576 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14577 spec->cdefine.platform_type == 1)
14578 alc_codec_rename(codec, "ALC271X");
14579 else
14580 alc_codec_rename(codec, "ALC259");
84898e87 14581 is_alc269vb = 1;
c027ddcd
KY
14582 } else
14583 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14584
f6a92248
KY
14585 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14586 alc269_models,
14587 alc269_cfg_tbl);
14588
14589 if (board_config < 0) {
9a11f1aa
TI
14590 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14591 codec->chip_name);
f6a92248
KY
14592 board_config = ALC269_AUTO;
14593 }
14594
ff818c24
TI
14595 if (board_config == ALC269_AUTO)
14596 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14597
f6a92248
KY
14598 if (board_config == ALC269_AUTO) {
14599 /* automatic parse from the BIOS config */
14600 err = alc269_parse_auto_config(codec);
14601 if (err < 0) {
14602 alc_free(codec);
14603 return err;
14604 } else if (!err) {
14605 printk(KERN_INFO
14606 "hda_codec: Cannot set up configuration "
14607 "from BIOS. Using base mode...\n");
14608 board_config = ALC269_BASIC;
14609 }
14610 }
14611
dc1eae25 14612 if (has_cdefine_beep(codec)) {
8af2591d
TI
14613 err = snd_hda_attach_beep_device(codec, 0x1);
14614 if (err < 0) {
14615 alc_free(codec);
14616 return err;
14617 }
680cd536
KK
14618 }
14619
f6a92248 14620 if (board_config != ALC269_AUTO)
e9c364c0 14621 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14622
84898e87 14623 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14624 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14625 * fix the sample rate of analog I/O to 44.1kHz
14626 */
14627 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14628 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14629 } else if (spec->dual_adc_switch) {
14630 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14631 /* switch ADC dynamically */
14632 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14633 } else {
14634 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14635 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14636 }
f6a92248
KY
14637 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14638 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14639
6694635d
TI
14640 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14641 if (!is_alc269vb) {
14642 spec->adc_nids = alc269_adc_nids;
14643 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14644 spec->capsrc_nids = alc269_capsrc_nids;
14645 } else {
14646 spec->adc_nids = alc269vb_adc_nids;
14647 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14648 spec->capsrc_nids = alc269vb_capsrc_nids;
14649 }
84898e87
KY
14650 }
14651
f9e336f6 14652 if (!spec->cap_mixer)
b59bdf3b 14653 set_capture_mixer(codec);
dc1eae25 14654 if (has_cdefine_beep(codec))
da00c244 14655 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14656
ff818c24
TI
14657 if (board_config == ALC269_AUTO)
14658 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14659
100d5eb3
TI
14660 spec->vmaster_nid = 0x02;
14661
f6a92248
KY
14662 codec->patch_ops = alc_patch_ops;
14663 if (board_config == ALC269_AUTO)
14664 spec->init_hook = alc269_auto_init;
14665#ifdef CONFIG_SND_HDA_POWER_SAVE
14666 if (!spec->loopback.amplist)
14667 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14668 if (alc269_mic2_for_mute_led(codec))
14669 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14670#endif
14671
14672 return 0;
14673}
14674
df694daa
KY
14675/*
14676 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14677 */
14678
14679/*
14680 * set the path ways for 2 channel output
14681 * need to set the codec line out and mic 1 pin widgets to inputs
14682 */
14683static struct hda_verb alc861_threestack_ch2_init[] = {
14684 /* set pin widget 1Ah (line in) for input */
14685 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14686 /* set pin widget 18h (mic1/2) for input, for mic also enable
14687 * the vref
14688 */
df694daa
KY
14689 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14690
9c7f852e
TI
14691 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14692#if 0
14693 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14694 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14695#endif
df694daa
KY
14696 { } /* end */
14697};
14698/*
14699 * 6ch mode
14700 * need to set the codec line out and mic 1 pin widgets to outputs
14701 */
14702static struct hda_verb alc861_threestack_ch6_init[] = {
14703 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14704 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14705 /* set pin widget 18h (mic1) for output (CLFE)*/
14706 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14707
14708 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14709 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14710
9c7f852e
TI
14711 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14712#if 0
14713 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14714 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14715#endif
df694daa
KY
14716 { } /* end */
14717};
14718
14719static struct hda_channel_mode alc861_threestack_modes[2] = {
14720 { 2, alc861_threestack_ch2_init },
14721 { 6, alc861_threestack_ch6_init },
14722};
22309c3e
TI
14723/* Set mic1 as input and unmute the mixer */
14724static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14726 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14727 { } /* end */
14728};
14729/* Set mic1 as output and mute mixer */
14730static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14731 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14732 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14733 { } /* end */
14734};
14735
14736static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14737 { 2, alc861_uniwill_m31_ch2_init },
14738 { 4, alc861_uniwill_m31_ch4_init },
14739};
df694daa 14740
7cdbff94
MD
14741/* Set mic1 and line-in as input and unmute the mixer */
14742static struct hda_verb alc861_asus_ch2_init[] = {
14743 /* set pin widget 1Ah (line in) for input */
14744 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14745 /* set pin widget 18h (mic1/2) for input, for mic also enable
14746 * the vref
14747 */
7cdbff94
MD
14748 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14749
14750 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14751#if 0
14752 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14753 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14754#endif
14755 { } /* end */
14756};
14757/* Set mic1 nad line-in as output and mute mixer */
14758static struct hda_verb alc861_asus_ch6_init[] = {
14759 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14760 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14761 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14762 /* set pin widget 18h (mic1) for output (CLFE)*/
14763 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14764 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14765 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14766 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14767
14768 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14769#if 0
14770 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14771 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14772#endif
14773 { } /* end */
14774};
14775
14776static struct hda_channel_mode alc861_asus_modes[2] = {
14777 { 2, alc861_asus_ch2_init },
14778 { 6, alc861_asus_ch6_init },
14779};
14780
df694daa
KY
14781/* patch-ALC861 */
14782
14783static struct snd_kcontrol_new alc861_base_mixer[] = {
14784 /* output mixer control */
14785 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14786 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14787 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14788 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14789 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14790
14791 /*Input mixer control */
14792 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14793 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14794 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14795 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14796 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14797 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14799 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14800 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14802
df694daa
KY
14803 { } /* end */
14804};
14805
14806static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14807 /* output mixer control */
14808 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14809 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14810 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14811 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14812 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14813
14814 /* Input mixer control */
14815 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14816 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14817 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14818 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14819 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14820 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14822 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14823 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14824 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14825
df694daa
KY
14826 {
14827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14828 .name = "Channel Mode",
14829 .info = alc_ch_mode_info,
14830 .get = alc_ch_mode_get,
14831 .put = alc_ch_mode_put,
14832 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14833 },
14834 { } /* end */
a53d1aec
TD
14835};
14836
d1d985f0 14837static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14838 /* output mixer control */
14839 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14841 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14842
a53d1aec 14843 { } /* end */
f12ab1e0 14844};
a53d1aec 14845
22309c3e
TI
14846static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14847 /* output mixer control */
14848 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14849 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14850 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14851 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14852 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14853
14854 /* Input mixer control */
14855 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14856 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14857 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14858 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14859 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14860 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14862 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14863 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14865
22309c3e
TI
14866 {
14867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14868 .name = "Channel Mode",
14869 .info = alc_ch_mode_info,
14870 .get = alc_ch_mode_get,
14871 .put = alc_ch_mode_put,
14872 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14873 },
14874 { } /* end */
f12ab1e0 14875};
7cdbff94
MD
14876
14877static struct snd_kcontrol_new alc861_asus_mixer[] = {
14878 /* output mixer control */
14879 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14880 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14881 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14882 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14883 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14884
14885 /* Input mixer control */
14886 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14887 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14888 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14889 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14890 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14891 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14893 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14896
7cdbff94
MD
14897 {
14898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14899 .name = "Channel Mode",
14900 .info = alc_ch_mode_info,
14901 .get = alc_ch_mode_get,
14902 .put = alc_ch_mode_put,
14903 .private_value = ARRAY_SIZE(alc861_asus_modes),
14904 },
14905 { }
56bb0cab
TI
14906};
14907
14908/* additional mixer */
d1d985f0 14909static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14910 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14911 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14912 { }
14913};
7cdbff94 14914
df694daa
KY
14915/*
14916 * generic initialization of ADC, input mixers and output mixers
14917 */
14918static struct hda_verb alc861_base_init_verbs[] = {
14919 /*
14920 * Unmute ADC0 and set the default input to mic-in
14921 */
14922 /* port-A for surround (rear panel) */
14923 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14924 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14925 /* port-B for mic-in (rear panel) with vref */
14926 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14927 /* port-C for line-in (rear panel) */
14928 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14929 /* port-D for Front */
14930 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14931 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14932 /* port-E for HP out (front panel) */
14933 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14934 /* route front PCM to HP */
9dece1d7 14935 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14936 /* port-F for mic-in (front panel) with vref */
14937 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14938 /* port-G for CLFE (rear panel) */
14939 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14940 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14941 /* port-H for side (rear panel) */
14942 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14943 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14944 /* CD-in */
14945 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14946 /* route front mic to ADC1*/
14947 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14949
df694daa
KY
14950 /* Unmute DAC0~3 & spdif out*/
14951 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14952 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14953 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14954 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14956
df694daa
KY
14957 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14958 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14959 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14960 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14961 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14962
df694daa
KY
14963 /* Unmute Stereo Mixer 15 */
14964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14966 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14968
14969 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14970 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14971 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14972 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14974 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14975 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14976 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14977 /* hp used DAC 3 (Front) */
14978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14979 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14980
14981 { }
14982};
14983
14984static struct hda_verb alc861_threestack_init_verbs[] = {
14985 /*
14986 * Unmute ADC0 and set the default input to mic-in
14987 */
14988 /* port-A for surround (rear panel) */
14989 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14990 /* port-B for mic-in (rear panel) with vref */
14991 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14992 /* port-C for line-in (rear panel) */
14993 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14994 /* port-D for Front */
14995 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14996 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14997 /* port-E for HP out (front panel) */
14998 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14999 /* route front PCM to HP */
9dece1d7 15000 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15001 /* port-F for mic-in (front panel) with vref */
15002 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15003 /* port-G for CLFE (rear panel) */
15004 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15005 /* port-H for side (rear panel) */
15006 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15007 /* CD-in */
15008 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15009 /* route front mic to ADC1*/
15010 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15011 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15012 /* Unmute DAC0~3 & spdif out*/
15013 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15014 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15015 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15016 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15018
df694daa
KY
15019 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15020 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15021 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15022 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15023 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15024
df694daa
KY
15025 /* Unmute Stereo Mixer 15 */
15026 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15028 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15029 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15030
15031 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15032 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15033 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15034 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15035 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15036 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15038 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15039 /* hp used DAC 3 (Front) */
15040 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15042 { }
15043};
22309c3e
TI
15044
15045static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15046 /*
15047 * Unmute ADC0 and set the default input to mic-in
15048 */
15049 /* port-A for surround (rear panel) */
15050 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15051 /* port-B for mic-in (rear panel) with vref */
15052 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15053 /* port-C for line-in (rear panel) */
15054 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15055 /* port-D for Front */
15056 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15057 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15058 /* port-E for HP out (front panel) */
f12ab1e0
TI
15059 /* this has to be set to VREF80 */
15060 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15061 /* route front PCM to HP */
9dece1d7 15062 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15063 /* port-F for mic-in (front panel) with vref */
15064 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15065 /* port-G for CLFE (rear panel) */
15066 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15067 /* port-H for side (rear panel) */
15068 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15069 /* CD-in */
15070 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15071 /* route front mic to ADC1*/
15072 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15074 /* Unmute DAC0~3 & spdif out*/
15075 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15076 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15077 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15078 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15080
22309c3e
TI
15081 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15082 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15083 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15084 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15085 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15086
22309c3e
TI
15087 /* Unmute Stereo Mixer 15 */
15088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15092
15093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15095 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15096 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15097 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15100 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15101 /* hp used DAC 3 (Front) */
15102 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15103 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15104 { }
15105};
15106
7cdbff94
MD
15107static struct hda_verb alc861_asus_init_verbs[] = {
15108 /*
15109 * Unmute ADC0 and set the default input to mic-in
15110 */
f12ab1e0
TI
15111 /* port-A for surround (rear panel)
15112 * according to codec#0 this is the HP jack
15113 */
7cdbff94
MD
15114 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15115 /* route front PCM to HP */
15116 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15117 /* port-B for mic-in (rear panel) with vref */
15118 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15119 /* port-C for line-in (rear panel) */
15120 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15121 /* port-D for Front */
15122 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15123 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15124 /* port-E for HP out (front panel) */
f12ab1e0
TI
15125 /* this has to be set to VREF80 */
15126 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15127 /* route front PCM to HP */
9dece1d7 15128 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15129 /* port-F for mic-in (front panel) with vref */
15130 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15131 /* port-G for CLFE (rear panel) */
15132 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15133 /* port-H for side (rear panel) */
15134 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15135 /* CD-in */
15136 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15137 /* route front mic to ADC1*/
15138 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15139 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15140 /* Unmute DAC0~3 & spdif out*/
15141 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15142 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15143 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15144 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15146 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15147 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15149 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15150 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15151
7cdbff94
MD
15152 /* Unmute Stereo Mixer 15 */
15153 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15154 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15155 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15157
15158 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15159 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15160 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15161 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15162 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15165 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15166 /* hp used DAC 3 (Front) */
15167 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15169 { }
15170};
15171
56bb0cab
TI
15172/* additional init verbs for ASUS laptops */
15173static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15174 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15175 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15176 { }
15177};
7cdbff94 15178
df694daa
KY
15179/*
15180 * generic initialization of ADC, input mixers and output mixers
15181 */
15182static struct hda_verb alc861_auto_init_verbs[] = {
15183 /*
15184 * Unmute ADC0 and set the default input to mic-in
15185 */
f12ab1e0 15186 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15188
df694daa
KY
15189 /* Unmute DAC0~3 & spdif out*/
15190 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15191 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15192 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15193 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15195
df694daa
KY
15196 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15197 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15198 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15199 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15200 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15201
df694daa
KY
15202 /* Unmute Stereo Mixer 15 */
15203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15207
1c20930a
TI
15208 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15209 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15210 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15211 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15212 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15215 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15216
15217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15220 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15221 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15223 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15224 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15225
f12ab1e0 15226 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15227
15228 { }
15229};
15230
a53d1aec
TD
15231static struct hda_verb alc861_toshiba_init_verbs[] = {
15232 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15233
a53d1aec
TD
15234 { }
15235};
15236
15237/* toggle speaker-output according to the hp-jack state */
15238static void alc861_toshiba_automute(struct hda_codec *codec)
15239{
864f92be 15240 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15241
47fd830a
TI
15242 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15243 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15244 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15245 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15246}
15247
15248static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15249 unsigned int res)
15250{
a53d1aec
TD
15251 if ((res >> 26) == ALC880_HP_EVENT)
15252 alc861_toshiba_automute(codec);
15253}
15254
def319f9 15255/* pcm configuration: identical with ALC880 */
df694daa
KY
15256#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15257#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15258#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15259#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15260
15261
15262#define ALC861_DIGOUT_NID 0x07
15263
15264static struct hda_channel_mode alc861_8ch_modes[1] = {
15265 { 8, NULL }
15266};
15267
15268static hda_nid_t alc861_dac_nids[4] = {
15269 /* front, surround, clfe, side */
15270 0x03, 0x06, 0x05, 0x04
15271};
15272
9c7f852e
TI
15273static hda_nid_t alc660_dac_nids[3] = {
15274 /* front, clfe, surround */
15275 0x03, 0x05, 0x06
15276};
15277
df694daa
KY
15278static hda_nid_t alc861_adc_nids[1] = {
15279 /* ADC0-2 */
15280 0x08,
15281};
15282
15283static struct hda_input_mux alc861_capture_source = {
15284 .num_items = 5,
15285 .items = {
15286 { "Mic", 0x0 },
15287 { "Front Mic", 0x3 },
15288 { "Line", 0x1 },
15289 { "CD", 0x4 },
15290 { "Mixer", 0x5 },
15291 },
15292};
15293
1c20930a
TI
15294static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15295{
15296 struct alc_spec *spec = codec->spec;
15297 hda_nid_t mix, srcs[5];
15298 int i, j, num;
15299
15300 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15301 return 0;
15302 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15303 if (num < 0)
15304 return 0;
15305 for (i = 0; i < num; i++) {
15306 unsigned int type;
a22d543a 15307 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15308 if (type != AC_WID_AUD_OUT)
15309 continue;
15310 for (j = 0; j < spec->multiout.num_dacs; j++)
15311 if (spec->multiout.dac_nids[j] == srcs[i])
15312 break;
15313 if (j >= spec->multiout.num_dacs)
15314 return srcs[i];
15315 }
15316 return 0;
15317}
15318
df694daa 15319/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15320static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15321 const struct auto_pin_cfg *cfg)
df694daa 15322{
1c20930a 15323 struct alc_spec *spec = codec->spec;
df694daa 15324 int i;
1c20930a 15325 hda_nid_t nid, dac;
df694daa
KY
15326
15327 spec->multiout.dac_nids = spec->private_dac_nids;
15328 for (i = 0; i < cfg->line_outs; i++) {
15329 nid = cfg->line_out_pins[i];
1c20930a
TI
15330 dac = alc861_look_for_dac(codec, nid);
15331 if (!dac)
15332 continue;
15333 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15334 }
df694daa
KY
15335 return 0;
15336}
15337
1c20930a
TI
15338static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15339 hda_nid_t nid, unsigned int chs)
15340{
0afe5f89 15341 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15342 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15343}
15344
df694daa 15345/* add playback controls from the parsed DAC table */
1c20930a 15346static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15347 const struct auto_pin_cfg *cfg)
15348{
1c20930a 15349 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15350 static const char *chname[4] = {
15351 "Front", "Surround", NULL /*CLFE*/, "Side"
15352 };
df694daa 15353 hda_nid_t nid;
1c20930a
TI
15354 int i, err;
15355
15356 if (cfg->line_outs == 1) {
15357 const char *pfx = NULL;
15358 if (!cfg->hp_outs)
15359 pfx = "Master";
15360 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15361 pfx = "Speaker";
15362 if (pfx) {
15363 nid = spec->multiout.dac_nids[0];
15364 return alc861_create_out_sw(codec, pfx, nid, 3);
15365 }
15366 }
df694daa
KY
15367
15368 for (i = 0; i < cfg->line_outs; i++) {
15369 nid = spec->multiout.dac_nids[i];
f12ab1e0 15370 if (!nid)
df694daa 15371 continue;
1c20930a 15372 if (i == 2) {
df694daa 15373 /* Center/LFE */
1c20930a 15374 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15375 if (err < 0)
df694daa 15376 return err;
1c20930a 15377 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15378 if (err < 0)
df694daa
KY
15379 return err;
15380 } else {
1c20930a 15381 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15382 if (err < 0)
df694daa
KY
15383 return err;
15384 }
15385 }
15386 return 0;
15387}
15388
1c20930a 15389static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15390{
1c20930a 15391 struct alc_spec *spec = codec->spec;
df694daa
KY
15392 int err;
15393 hda_nid_t nid;
15394
f12ab1e0 15395 if (!pin)
df694daa
KY
15396 return 0;
15397
15398 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15399 nid = alc861_look_for_dac(codec, pin);
15400 if (nid) {
15401 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15402 if (err < 0)
15403 return err;
15404 spec->multiout.hp_nid = nid;
15405 }
df694daa
KY
15406 }
15407 return 0;
15408}
15409
15410/* create playback/capture controls for input pins */
05f5f477 15411static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15412 const struct auto_pin_cfg *cfg)
df694daa 15413{
05f5f477 15414 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15415}
15416
f12ab1e0
TI
15417static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15418 hda_nid_t nid,
1c20930a 15419 int pin_type, hda_nid_t dac)
df694daa 15420{
1c20930a
TI
15421 hda_nid_t mix, srcs[5];
15422 int i, num;
15423
564c5bea
JL
15424 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15425 pin_type);
1c20930a 15426 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15427 AMP_OUT_UNMUTE);
1c20930a
TI
15428 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15429 return;
15430 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15431 if (num < 0)
15432 return;
15433 for (i = 0; i < num; i++) {
15434 unsigned int mute;
15435 if (srcs[i] == dac || srcs[i] == 0x15)
15436 mute = AMP_IN_UNMUTE(i);
15437 else
15438 mute = AMP_IN_MUTE(i);
15439 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15440 mute);
15441 }
df694daa
KY
15442}
15443
15444static void alc861_auto_init_multi_out(struct hda_codec *codec)
15445{
15446 struct alc_spec *spec = codec->spec;
15447 int i;
15448
15449 for (i = 0; i < spec->autocfg.line_outs; i++) {
15450 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15451 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15452 if (nid)
baba8ee9 15453 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15454 spec->multiout.dac_nids[i]);
df694daa
KY
15455 }
15456}
15457
15458static void alc861_auto_init_hp_out(struct hda_codec *codec)
15459{
15460 struct alc_spec *spec = codec->spec;
df694daa 15461
15870f05
TI
15462 if (spec->autocfg.hp_outs)
15463 alc861_auto_set_output_and_unmute(codec,
15464 spec->autocfg.hp_pins[0],
15465 PIN_HP,
1c20930a 15466 spec->multiout.hp_nid);
15870f05
TI
15467 if (spec->autocfg.speaker_outs)
15468 alc861_auto_set_output_and_unmute(codec,
15469 spec->autocfg.speaker_pins[0],
15470 PIN_OUT,
1c20930a 15471 spec->multiout.dac_nids[0]);
df694daa
KY
15472}
15473
15474static void alc861_auto_init_analog_input(struct hda_codec *codec)
15475{
15476 struct alc_spec *spec = codec->spec;
15477 int i;
15478
15479 for (i = 0; i < AUTO_PIN_LAST; i++) {
15480 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15481 if (nid >= 0x0c && nid <= 0x11)
15482 alc_set_input_pin(codec, nid, i);
df694daa
KY
15483 }
15484}
15485
15486/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15487/* return 1 if successful, 0 if the proper config is not found,
15488 * or a negative error code
15489 */
df694daa
KY
15490static int alc861_parse_auto_config(struct hda_codec *codec)
15491{
15492 struct alc_spec *spec = codec->spec;
15493 int err;
15494 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15495
f12ab1e0
TI
15496 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15497 alc861_ignore);
15498 if (err < 0)
df694daa 15499 return err;
f12ab1e0 15500 if (!spec->autocfg.line_outs)
df694daa
KY
15501 return 0; /* can't find valid BIOS pin config */
15502
1c20930a 15503 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15504 if (err < 0)
15505 return err;
1c20930a 15506 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15507 if (err < 0)
15508 return err;
1c20930a 15509 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15510 if (err < 0)
15511 return err;
05f5f477 15512 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15513 if (err < 0)
df694daa
KY
15514 return err;
15515
15516 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15517
0852d7a6 15518 if (spec->autocfg.dig_outs)
df694daa
KY
15519 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15520
603c4019 15521 if (spec->kctls.list)
d88897ea 15522 add_mixer(spec, spec->kctls.list);
df694daa 15523
d88897ea 15524 add_verb(spec, alc861_auto_init_verbs);
df694daa 15525
a1e8d2da 15526 spec->num_mux_defs = 1;
61b9b9b1 15527 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15528
15529 spec->adc_nids = alc861_adc_nids;
15530 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15531 set_capture_mixer(codec);
df694daa 15532
6227cdce 15533 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15534
df694daa
KY
15535 return 1;
15536}
15537
ae6b813a
TI
15538/* additional initialization for auto-configuration model */
15539static void alc861_auto_init(struct hda_codec *codec)
df694daa 15540{
f6c7e546 15541 struct alc_spec *spec = codec->spec;
df694daa
KY
15542 alc861_auto_init_multi_out(codec);
15543 alc861_auto_init_hp_out(codec);
15544 alc861_auto_init_analog_input(codec);
f6c7e546 15545 if (spec->unsol_event)
7fb0d78f 15546 alc_inithook(codec);
df694daa
KY
15547}
15548
cb53c626
TI
15549#ifdef CONFIG_SND_HDA_POWER_SAVE
15550static struct hda_amp_list alc861_loopbacks[] = {
15551 { 0x15, HDA_INPUT, 0 },
15552 { 0x15, HDA_INPUT, 1 },
15553 { 0x15, HDA_INPUT, 2 },
15554 { 0x15, HDA_INPUT, 3 },
15555 { } /* end */
15556};
15557#endif
15558
df694daa
KY
15559
15560/*
15561 * configuration and preset
15562 */
f5fcc13c
TI
15563static const char *alc861_models[ALC861_MODEL_LAST] = {
15564 [ALC861_3ST] = "3stack",
15565 [ALC660_3ST] = "3stack-660",
15566 [ALC861_3ST_DIG] = "3stack-dig",
15567 [ALC861_6ST_DIG] = "6stack-dig",
15568 [ALC861_UNIWILL_M31] = "uniwill-m31",
15569 [ALC861_TOSHIBA] = "toshiba",
15570 [ALC861_ASUS] = "asus",
15571 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15572 [ALC861_AUTO] = "auto",
15573};
15574
15575static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15576 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15577 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15578 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15579 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15580 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15581 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15582 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15583 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15584 * Any other models that need this preset?
15585 */
15586 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15587 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15588 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15589 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15590 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15591 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15592 /* FIXME: the below seems conflict */
15593 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15594 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15595 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15596 {}
15597};
15598
15599static struct alc_config_preset alc861_presets[] = {
15600 [ALC861_3ST] = {
15601 .mixers = { alc861_3ST_mixer },
15602 .init_verbs = { alc861_threestack_init_verbs },
15603 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15604 .dac_nids = alc861_dac_nids,
15605 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15606 .channel_mode = alc861_threestack_modes,
4e195a7b 15607 .need_dac_fix = 1,
df694daa
KY
15608 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15609 .adc_nids = alc861_adc_nids,
15610 .input_mux = &alc861_capture_source,
15611 },
15612 [ALC861_3ST_DIG] = {
15613 .mixers = { alc861_base_mixer },
15614 .init_verbs = { alc861_threestack_init_verbs },
15615 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15616 .dac_nids = alc861_dac_nids,
15617 .dig_out_nid = ALC861_DIGOUT_NID,
15618 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15619 .channel_mode = alc861_threestack_modes,
4e195a7b 15620 .need_dac_fix = 1,
df694daa
KY
15621 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15622 .adc_nids = alc861_adc_nids,
15623 .input_mux = &alc861_capture_source,
15624 },
15625 [ALC861_6ST_DIG] = {
15626 .mixers = { alc861_base_mixer },
15627 .init_verbs = { alc861_base_init_verbs },
15628 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15629 .dac_nids = alc861_dac_nids,
15630 .dig_out_nid = ALC861_DIGOUT_NID,
15631 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15632 .channel_mode = alc861_8ch_modes,
15633 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15634 .adc_nids = alc861_adc_nids,
15635 .input_mux = &alc861_capture_source,
15636 },
9c7f852e
TI
15637 [ALC660_3ST] = {
15638 .mixers = { alc861_3ST_mixer },
15639 .init_verbs = { alc861_threestack_init_verbs },
15640 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15641 .dac_nids = alc660_dac_nids,
15642 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15643 .channel_mode = alc861_threestack_modes,
4e195a7b 15644 .need_dac_fix = 1,
9c7f852e
TI
15645 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15646 .adc_nids = alc861_adc_nids,
15647 .input_mux = &alc861_capture_source,
15648 },
22309c3e
TI
15649 [ALC861_UNIWILL_M31] = {
15650 .mixers = { alc861_uniwill_m31_mixer },
15651 .init_verbs = { alc861_uniwill_m31_init_verbs },
15652 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15653 .dac_nids = alc861_dac_nids,
15654 .dig_out_nid = ALC861_DIGOUT_NID,
15655 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15656 .channel_mode = alc861_uniwill_m31_modes,
15657 .need_dac_fix = 1,
15658 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15659 .adc_nids = alc861_adc_nids,
15660 .input_mux = &alc861_capture_source,
15661 },
a53d1aec
TD
15662 [ALC861_TOSHIBA] = {
15663 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15664 .init_verbs = { alc861_base_init_verbs,
15665 alc861_toshiba_init_verbs },
a53d1aec
TD
15666 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15667 .dac_nids = alc861_dac_nids,
15668 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15669 .channel_mode = alc883_3ST_2ch_modes,
15670 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15671 .adc_nids = alc861_adc_nids,
15672 .input_mux = &alc861_capture_source,
15673 .unsol_event = alc861_toshiba_unsol_event,
15674 .init_hook = alc861_toshiba_automute,
15675 },
7cdbff94
MD
15676 [ALC861_ASUS] = {
15677 .mixers = { alc861_asus_mixer },
15678 .init_verbs = { alc861_asus_init_verbs },
15679 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15680 .dac_nids = alc861_dac_nids,
15681 .dig_out_nid = ALC861_DIGOUT_NID,
15682 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15683 .channel_mode = alc861_asus_modes,
15684 .need_dac_fix = 1,
15685 .hp_nid = 0x06,
15686 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15687 .adc_nids = alc861_adc_nids,
15688 .input_mux = &alc861_capture_source,
15689 },
56bb0cab
TI
15690 [ALC861_ASUS_LAPTOP] = {
15691 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15692 .init_verbs = { alc861_asus_init_verbs,
15693 alc861_asus_laptop_init_verbs },
15694 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15695 .dac_nids = alc861_dac_nids,
15696 .dig_out_nid = ALC861_DIGOUT_NID,
15697 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15698 .channel_mode = alc883_3ST_2ch_modes,
15699 .need_dac_fix = 1,
15700 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15701 .adc_nids = alc861_adc_nids,
15702 .input_mux = &alc861_capture_source,
15703 },
15704};
df694daa 15705
cfc9b06f
TI
15706/* Pin config fixes */
15707enum {
15708 PINFIX_FSC_AMILO_PI1505,
15709};
15710
15711static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15712 { 0x0b, 0x0221101f }, /* HP */
15713 { 0x0f, 0x90170310 }, /* speaker */
15714 { }
15715};
15716
15717static const struct alc_fixup alc861_fixups[] = {
15718 [PINFIX_FSC_AMILO_PI1505] = {
15719 .pins = alc861_fsc_amilo_pi1505_pinfix
15720 },
15721};
15722
15723static struct snd_pci_quirk alc861_fixup_tbl[] = {
15724 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15725 {}
15726};
df694daa
KY
15727
15728static int patch_alc861(struct hda_codec *codec)
15729{
15730 struct alc_spec *spec;
15731 int board_config;
15732 int err;
15733
dc041e0b 15734 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15735 if (spec == NULL)
15736 return -ENOMEM;
15737
f12ab1e0 15738 codec->spec = spec;
df694daa 15739
f5fcc13c
TI
15740 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15741 alc861_models,
15742 alc861_cfg_tbl);
9c7f852e 15743
f5fcc13c 15744 if (board_config < 0) {
9a11f1aa
TI
15745 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15746 codec->chip_name);
df694daa
KY
15747 board_config = ALC861_AUTO;
15748 }
15749
7fa90e87
TI
15750 if (board_config == ALC861_AUTO)
15751 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 15752
df694daa
KY
15753 if (board_config == ALC861_AUTO) {
15754 /* automatic parse from the BIOS config */
15755 err = alc861_parse_auto_config(codec);
15756 if (err < 0) {
15757 alc_free(codec);
15758 return err;
f12ab1e0 15759 } else if (!err) {
9c7f852e
TI
15760 printk(KERN_INFO
15761 "hda_codec: Cannot set up configuration "
15762 "from BIOS. Using base mode...\n");
df694daa
KY
15763 board_config = ALC861_3ST_DIG;
15764 }
15765 }
15766
680cd536
KK
15767 err = snd_hda_attach_beep_device(codec, 0x23);
15768 if (err < 0) {
15769 alc_free(codec);
15770 return err;
15771 }
15772
df694daa 15773 if (board_config != ALC861_AUTO)
e9c364c0 15774 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15775
df694daa
KY
15776 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15777 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15778
df694daa
KY
15779 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15780 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15781
c7a8eb10
TI
15782 if (!spec->cap_mixer)
15783 set_capture_mixer(codec);
45bdd1c1
TI
15784 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15785
2134ea4f
TI
15786 spec->vmaster_nid = 0x03;
15787
7fa90e87
TI
15788 if (board_config == ALC861_AUTO)
15789 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15790
df694daa 15791 codec->patch_ops = alc_patch_ops;
c97259df 15792 if (board_config == ALC861_AUTO) {
ae6b813a 15793 spec->init_hook = alc861_auto_init;
c97259df
DC
15794#ifdef CONFIG_SND_HDA_POWER_SAVE
15795 spec->power_hook = alc_power_eapd;
15796#endif
15797 }
cb53c626
TI
15798#ifdef CONFIG_SND_HDA_POWER_SAVE
15799 if (!spec->loopback.amplist)
15800 spec->loopback.amplist = alc861_loopbacks;
15801#endif
ea1fb29a 15802
1da177e4
LT
15803 return 0;
15804}
15805
f32610ed
JS
15806/*
15807 * ALC861-VD support
15808 *
15809 * Based on ALC882
15810 *
15811 * In addition, an independent DAC
15812 */
15813#define ALC861VD_DIGOUT_NID 0x06
15814
15815static hda_nid_t alc861vd_dac_nids[4] = {
15816 /* front, surr, clfe, side surr */
15817 0x02, 0x03, 0x04, 0x05
15818};
15819
15820/* dac_nids for ALC660vd are in a different order - according to
15821 * Realtek's driver.
def319f9 15822 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15823 * of ALC660vd codecs, but for now there is only 3stack mixer
15824 * - and it is the same as in 861vd.
15825 * adc_nids in ALC660vd are (is) the same as in 861vd
15826 */
15827static hda_nid_t alc660vd_dac_nids[3] = {
15828 /* front, rear, clfe, rear_surr */
15829 0x02, 0x04, 0x03
15830};
15831
15832static hda_nid_t alc861vd_adc_nids[1] = {
15833 /* ADC0 */
15834 0x09,
15835};
15836
e1406348
TI
15837static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15838
f32610ed
JS
15839/* input MUX */
15840/* FIXME: should be a matrix-type input source selection */
15841static struct hda_input_mux alc861vd_capture_source = {
15842 .num_items = 4,
15843 .items = {
15844 { "Mic", 0x0 },
15845 { "Front Mic", 0x1 },
15846 { "Line", 0x2 },
15847 { "CD", 0x4 },
15848 },
15849};
15850
272a527c 15851static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15852 .num_items = 2,
272a527c 15853 .items = {
b419f346
TD
15854 { "Ext Mic", 0x0 },
15855 { "Int Mic", 0x1 },
272a527c
KY
15856 },
15857};
15858
d1a991a6
KY
15859static struct hda_input_mux alc861vd_hp_capture_source = {
15860 .num_items = 2,
15861 .items = {
15862 { "Front Mic", 0x0 },
15863 { "ATAPI Mic", 0x1 },
15864 },
15865};
15866
f32610ed
JS
15867/*
15868 * 2ch mode
15869 */
15870static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15871 { 2, NULL }
15872};
15873
15874/*
15875 * 6ch mode
15876 */
15877static struct hda_verb alc861vd_6stack_ch6_init[] = {
15878 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15879 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15880 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15881 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15882 { } /* end */
15883};
15884
15885/*
15886 * 8ch mode
15887 */
15888static struct hda_verb alc861vd_6stack_ch8_init[] = {
15889 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15890 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15891 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15892 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15893 { } /* end */
15894};
15895
15896static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15897 { 6, alc861vd_6stack_ch6_init },
15898 { 8, alc861vd_6stack_ch8_init },
15899};
15900
15901static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15902 {
15903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15904 .name = "Channel Mode",
15905 .info = alc_ch_mode_info,
15906 .get = alc_ch_mode_get,
15907 .put = alc_ch_mode_put,
15908 },
15909 { } /* end */
15910};
15911
f32610ed
JS
15912/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15913 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15914 */
15915static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15916 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15917 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15918
15919 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15920 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15921
15922 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15923 HDA_OUTPUT),
15924 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15925 HDA_OUTPUT),
15926 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15927 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15928
15929 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15930 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15931
15932 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15933
15934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15937
15938 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15939 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15940 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15941
15942 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15943 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15944
15945 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15946 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15947
f32610ed
JS
15948 { } /* end */
15949};
15950
15951static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15953 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15954
15955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15956
15957 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15959 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15960
15961 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15962 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15963 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15964
15965 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15966 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15967
15968 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15969 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15970
f32610ed
JS
15971 { } /* end */
15972};
15973
bdd148a3
KY
15974static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15975 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15976 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15977 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15978
15979 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15980
15981 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15984
15985 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15986 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15987 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15988
15989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15991
15992 { } /* end */
15993};
15994
b419f346
TD
15995/* Pin assignment: Speaker=0x14, HP = 0x15,
15996 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
15997 */
15998static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
15999 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16000 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16001 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16002 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16003 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16004 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16005 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16006 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16007 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16008 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16009 { } /* end */
16010};
16011
d1a991a6
KY
16012/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16013 * Front Mic=0x18, ATAPI Mic = 0x19,
16014 */
16015static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16016 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16017 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16018 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16019 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16022 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16023 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16024
d1a991a6
KY
16025 { } /* end */
16026};
16027
f32610ed
JS
16028/*
16029 * generic initialization of ADC, input mixers and output mixers
16030 */
16031static struct hda_verb alc861vd_volume_init_verbs[] = {
16032 /*
16033 * Unmute ADC0 and set the default input to mic-in
16034 */
16035 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16036 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16037
16038 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16039 * the analog-loopback mixer widget
16040 */
16041 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16042 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16043 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16044 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16045 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16046 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16047
16048 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16053
16054 /*
16055 * Set up output mixers (0x02 - 0x05)
16056 */
16057 /* set vol=0 to output mixers */
16058 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16059 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16060 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16061 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16062
16063 /* set up input amps for analog loopback */
16064 /* Amp Indices: DAC = 0, mixer = 1 */
16065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16066 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16067 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16068 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16069 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16070 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16071 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16072 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16073
16074 { }
16075};
16076
16077/*
16078 * 3-stack pin configuration:
16079 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16080 */
16081static struct hda_verb alc861vd_3stack_init_verbs[] = {
16082 /*
16083 * Set pin mode and muting
16084 */
16085 /* set front pin widgets 0x14 for output */
16086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16088 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16089
16090 /* Mic (rear) pin: input vref at 80% */
16091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16093 /* Front Mic pin: input vref at 80% */
16094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16095 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16096 /* Line In pin: input */
16097 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16098 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16099 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16101 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16102 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16103 /* CD pin widget for input */
16104 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16105
16106 { }
16107};
16108
16109/*
16110 * 6-stack pin configuration:
16111 */
16112static struct hda_verb alc861vd_6stack_init_verbs[] = {
16113 /*
16114 * Set pin mode and muting
16115 */
16116 /* set front pin widgets 0x14 for output */
16117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16119 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16120
16121 /* Rear Pin: output 1 (0x0d) */
16122 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16123 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16125 /* CLFE Pin: output 2 (0x0e) */
16126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16127 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16128 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16129 /* Side Pin: output 3 (0x0f) */
16130 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16132 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16133
16134 /* Mic (rear) pin: input vref at 80% */
16135 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16136 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16137 /* Front Mic pin: input vref at 80% */
16138 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16139 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16140 /* Line In pin: input */
16141 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16142 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16143 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16144 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16145 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16146 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16147 /* CD pin widget for input */
16148 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16149
16150 { }
16151};
16152
bdd148a3
KY
16153static struct hda_verb alc861vd_eapd_verbs[] = {
16154 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16155 { }
16156};
16157
f9423e7a
KY
16158static struct hda_verb alc660vd_eapd_verbs[] = {
16159 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16160 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16161 { }
16162};
16163
bdd148a3
KY
16164static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16166 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16168 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16169 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16170 {}
16171};
16172
bdd148a3
KY
16173static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16174{
16175 unsigned int present;
16176 unsigned char bits;
16177
864f92be 16178 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16179 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16180
47fd830a
TI
16181 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16182 HDA_AMP_MUTE, bits);
bdd148a3
KY
16183}
16184
4f5d1706 16185static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16186{
a9fd4f3f 16187 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16188 spec->autocfg.hp_pins[0] = 0x1b;
16189 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16190}
16191
16192static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16193{
a9fd4f3f 16194 alc_automute_amp(codec);
bdd148a3
KY
16195 alc861vd_lenovo_mic_automute(codec);
16196}
16197
16198static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16199 unsigned int res)
16200{
16201 switch (res >> 26) {
bdd148a3
KY
16202 case ALC880_MIC_EVENT:
16203 alc861vd_lenovo_mic_automute(codec);
16204 break;
a9fd4f3f
TI
16205 default:
16206 alc_automute_amp_unsol_event(codec, res);
16207 break;
bdd148a3
KY
16208 }
16209}
16210
272a527c
KY
16211static struct hda_verb alc861vd_dallas_verbs[] = {
16212 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16213 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16214 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16215 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16216
16217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16223 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16225
272a527c
KY
16226 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16227 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16229 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16230 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16231 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16232 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16233 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16234
16235 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16236 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16237 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16238 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16239 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16240 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16241 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16242 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16243
16244 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16245 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16248
16249 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16250 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16251 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16252
16253 { } /* end */
16254};
16255
16256/* toggle speaker-output according to the hp-jack state */
4f5d1706 16257static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16258{
a9fd4f3f 16259 struct alc_spec *spec = codec->spec;
272a527c 16260
a9fd4f3f
TI
16261 spec->autocfg.hp_pins[0] = 0x15;
16262 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16263}
16264
cb53c626
TI
16265#ifdef CONFIG_SND_HDA_POWER_SAVE
16266#define alc861vd_loopbacks alc880_loopbacks
16267#endif
16268
def319f9 16269/* pcm configuration: identical with ALC880 */
f32610ed
JS
16270#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16271#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16272#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16273#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16274
16275/*
16276 * configuration and preset
16277 */
16278static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16279 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16280 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16281 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16282 [ALC861VD_3ST] = "3stack",
16283 [ALC861VD_3ST_DIG] = "3stack-digout",
16284 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16285 [ALC861VD_LENOVO] = "lenovo",
272a527c 16286 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16287 [ALC861VD_HP] = "hp",
f32610ed
JS
16288 [ALC861VD_AUTO] = "auto",
16289};
16290
16291static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16292 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16293 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16294 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16295 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16296 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16297 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16298 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16299 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16300 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16301 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16302 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16303 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16304 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16305 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16306 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16307 {}
16308};
16309
16310static struct alc_config_preset alc861vd_presets[] = {
16311 [ALC660VD_3ST] = {
16312 .mixers = { alc861vd_3st_mixer },
16313 .init_verbs = { alc861vd_volume_init_verbs,
16314 alc861vd_3stack_init_verbs },
16315 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16316 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16317 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16318 .channel_mode = alc861vd_3stack_2ch_modes,
16319 .input_mux = &alc861vd_capture_source,
16320 },
6963f84c
MC
16321 [ALC660VD_3ST_DIG] = {
16322 .mixers = { alc861vd_3st_mixer },
16323 .init_verbs = { alc861vd_volume_init_verbs,
16324 alc861vd_3stack_init_verbs },
16325 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16326 .dac_nids = alc660vd_dac_nids,
16327 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16328 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16329 .channel_mode = alc861vd_3stack_2ch_modes,
16330 .input_mux = &alc861vd_capture_source,
16331 },
f32610ed
JS
16332 [ALC861VD_3ST] = {
16333 .mixers = { alc861vd_3st_mixer },
16334 .init_verbs = { alc861vd_volume_init_verbs,
16335 alc861vd_3stack_init_verbs },
16336 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16337 .dac_nids = alc861vd_dac_nids,
16338 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16339 .channel_mode = alc861vd_3stack_2ch_modes,
16340 .input_mux = &alc861vd_capture_source,
16341 },
16342 [ALC861VD_3ST_DIG] = {
16343 .mixers = { alc861vd_3st_mixer },
16344 .init_verbs = { alc861vd_volume_init_verbs,
16345 alc861vd_3stack_init_verbs },
16346 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16347 .dac_nids = alc861vd_dac_nids,
16348 .dig_out_nid = ALC861VD_DIGOUT_NID,
16349 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16350 .channel_mode = alc861vd_3stack_2ch_modes,
16351 .input_mux = &alc861vd_capture_source,
16352 },
16353 [ALC861VD_6ST_DIG] = {
16354 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16355 .init_verbs = { alc861vd_volume_init_verbs,
16356 alc861vd_6stack_init_verbs },
16357 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16358 .dac_nids = alc861vd_dac_nids,
16359 .dig_out_nid = ALC861VD_DIGOUT_NID,
16360 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16361 .channel_mode = alc861vd_6stack_modes,
16362 .input_mux = &alc861vd_capture_source,
16363 },
bdd148a3
KY
16364 [ALC861VD_LENOVO] = {
16365 .mixers = { alc861vd_lenovo_mixer },
16366 .init_verbs = { alc861vd_volume_init_verbs,
16367 alc861vd_3stack_init_verbs,
16368 alc861vd_eapd_verbs,
16369 alc861vd_lenovo_unsol_verbs },
16370 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16371 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16372 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16373 .channel_mode = alc861vd_3stack_2ch_modes,
16374 .input_mux = &alc861vd_capture_source,
16375 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16376 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16377 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16378 },
272a527c
KY
16379 [ALC861VD_DALLAS] = {
16380 .mixers = { alc861vd_dallas_mixer },
16381 .init_verbs = { alc861vd_dallas_verbs },
16382 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16383 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16384 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16385 .channel_mode = alc861vd_3stack_2ch_modes,
16386 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16387 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16388 .setup = alc861vd_dallas_setup,
16389 .init_hook = alc_automute_amp,
d1a991a6
KY
16390 },
16391 [ALC861VD_HP] = {
16392 .mixers = { alc861vd_hp_mixer },
16393 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16394 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16395 .dac_nids = alc861vd_dac_nids,
d1a991a6 16396 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16397 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16398 .channel_mode = alc861vd_3stack_2ch_modes,
16399 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16400 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16401 .setup = alc861vd_dallas_setup,
16402 .init_hook = alc_automute_amp,
ea1fb29a 16403 },
13c94744
TI
16404 [ALC660VD_ASUS_V1S] = {
16405 .mixers = { alc861vd_lenovo_mixer },
16406 .init_verbs = { alc861vd_volume_init_verbs,
16407 alc861vd_3stack_init_verbs,
16408 alc861vd_eapd_verbs,
16409 alc861vd_lenovo_unsol_verbs },
16410 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16411 .dac_nids = alc660vd_dac_nids,
16412 .dig_out_nid = ALC861VD_DIGOUT_NID,
16413 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16414 .channel_mode = alc861vd_3stack_2ch_modes,
16415 .input_mux = &alc861vd_capture_source,
16416 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16417 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16418 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16419 },
f32610ed
JS
16420};
16421
16422/*
16423 * BIOS auto configuration
16424 */
05f5f477
TI
16425static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16426 const struct auto_pin_cfg *cfg)
16427{
6227cdce 16428 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16429}
16430
16431
f32610ed
JS
16432static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16433 hda_nid_t nid, int pin_type, int dac_idx)
16434{
f6c7e546 16435 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16436}
16437
16438static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16439{
16440 struct alc_spec *spec = codec->spec;
16441 int i;
16442
16443 for (i = 0; i <= HDA_SIDE; i++) {
16444 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16445 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16446 if (nid)
16447 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16448 pin_type, i);
f32610ed
JS
16449 }
16450}
16451
16452
16453static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16454{
16455 struct alc_spec *spec = codec->spec;
16456 hda_nid_t pin;
16457
16458 pin = spec->autocfg.hp_pins[0];
def319f9 16459 if (pin) /* connect to front and use dac 0 */
f32610ed 16460 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16461 pin = spec->autocfg.speaker_pins[0];
16462 if (pin)
16463 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16464}
16465
f32610ed
JS
16466#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16467
16468static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16469{
16470 struct alc_spec *spec = codec->spec;
16471 int i;
16472
16473 for (i = 0; i < AUTO_PIN_LAST; i++) {
16474 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16475 if (alc_is_input_pin(codec, nid)) {
23f0c048 16476 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16477 if (nid != ALC861VD_PIN_CD_NID &&
16478 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16479 snd_hda_codec_write(codec, nid, 0,
16480 AC_VERB_SET_AMP_GAIN_MUTE,
16481 AMP_OUT_MUTE);
16482 }
16483 }
16484}
16485
f511b01c
TI
16486#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16487
f32610ed
JS
16488#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16489#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16490
16491/* add playback controls from the parsed DAC table */
16492/* Based on ALC880 version. But ALC861VD has separate,
16493 * different NIDs for mute/unmute switch and volume control */
16494static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16495 const struct auto_pin_cfg *cfg)
16496{
f32610ed
JS
16497 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16498 hda_nid_t nid_v, nid_s;
16499 int i, err;
16500
16501 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16502 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16503 continue;
16504 nid_v = alc861vd_idx_to_mixer_vol(
16505 alc880_dac_to_idx(
16506 spec->multiout.dac_nids[i]));
16507 nid_s = alc861vd_idx_to_mixer_switch(
16508 alc880_dac_to_idx(
16509 spec->multiout.dac_nids[i]));
16510
16511 if (i == 2) {
16512 /* Center/LFE */
0afe5f89
TI
16513 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16514 "Center",
f12ab1e0
TI
16515 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16516 HDA_OUTPUT));
16517 if (err < 0)
f32610ed 16518 return err;
0afe5f89
TI
16519 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16520 "LFE",
f12ab1e0
TI
16521 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16522 HDA_OUTPUT));
16523 if (err < 0)
f32610ed 16524 return err;
0afe5f89
TI
16525 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16526 "Center",
f12ab1e0
TI
16527 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16528 HDA_INPUT));
16529 if (err < 0)
f32610ed 16530 return err;
0afe5f89
TI
16531 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16532 "LFE",
f12ab1e0
TI
16533 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16534 HDA_INPUT));
16535 if (err < 0)
f32610ed
JS
16536 return err;
16537 } else {
a4fcd491
TI
16538 const char *pfx;
16539 if (cfg->line_outs == 1 &&
16540 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16541 if (!cfg->hp_pins)
16542 pfx = "Speaker";
16543 else
16544 pfx = "PCM";
16545 } else
16546 pfx = chname[i];
0afe5f89 16547 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16548 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16549 HDA_OUTPUT));
16550 if (err < 0)
f32610ed 16551 return err;
a4fcd491
TI
16552 if (cfg->line_outs == 1 &&
16553 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16554 pfx = "Speaker";
0afe5f89 16555 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16556 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16557 HDA_INPUT));
16558 if (err < 0)
f32610ed
JS
16559 return err;
16560 }
16561 }
16562 return 0;
16563}
16564
16565/* add playback controls for speaker and HP outputs */
16566/* Based on ALC880 version. But ALC861VD has separate,
16567 * different NIDs for mute/unmute switch and volume control */
16568static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16569 hda_nid_t pin, const char *pfx)
16570{
16571 hda_nid_t nid_v, nid_s;
16572 int err;
f32610ed 16573
f12ab1e0 16574 if (!pin)
f32610ed
JS
16575 return 0;
16576
16577 if (alc880_is_fixed_pin(pin)) {
16578 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16579 /* specify the DAC as the extra output */
f12ab1e0 16580 if (!spec->multiout.hp_nid)
f32610ed
JS
16581 spec->multiout.hp_nid = nid_v;
16582 else
16583 spec->multiout.extra_out_nid[0] = nid_v;
16584 /* control HP volume/switch on the output mixer amp */
16585 nid_v = alc861vd_idx_to_mixer_vol(
16586 alc880_fixed_pin_idx(pin));
16587 nid_s = alc861vd_idx_to_mixer_switch(
16588 alc880_fixed_pin_idx(pin));
16589
0afe5f89 16590 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16591 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16592 if (err < 0)
f32610ed 16593 return err;
0afe5f89 16594 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16595 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16596 if (err < 0)
f32610ed
JS
16597 return err;
16598 } else if (alc880_is_multi_pin(pin)) {
16599 /* set manual connection */
16600 /* we have only a switch on HP-out PIN */
0afe5f89 16601 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16602 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16603 if (err < 0)
f32610ed
JS
16604 return err;
16605 }
16606 return 0;
16607}
16608
16609/* parse the BIOS configuration and set up the alc_spec
16610 * return 1 if successful, 0 if the proper config is not found,
16611 * or a negative error code
16612 * Based on ALC880 version - had to change it to override
16613 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16614static int alc861vd_parse_auto_config(struct hda_codec *codec)
16615{
16616 struct alc_spec *spec = codec->spec;
16617 int err;
16618 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16619
f12ab1e0
TI
16620 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16621 alc861vd_ignore);
16622 if (err < 0)
f32610ed 16623 return err;
f12ab1e0 16624 if (!spec->autocfg.line_outs)
f32610ed
JS
16625 return 0; /* can't find valid BIOS pin config */
16626
f12ab1e0
TI
16627 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16628 if (err < 0)
16629 return err;
16630 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16631 if (err < 0)
16632 return err;
16633 err = alc861vd_auto_create_extra_out(spec,
16634 spec->autocfg.speaker_pins[0],
16635 "Speaker");
16636 if (err < 0)
16637 return err;
16638 err = alc861vd_auto_create_extra_out(spec,
16639 spec->autocfg.hp_pins[0],
16640 "Headphone");
16641 if (err < 0)
16642 return err;
05f5f477 16643 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16644 if (err < 0)
f32610ed
JS
16645 return err;
16646
16647 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16648
0852d7a6 16649 if (spec->autocfg.dig_outs)
f32610ed
JS
16650 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16651
603c4019 16652 if (spec->kctls.list)
d88897ea 16653 add_mixer(spec, spec->kctls.list);
f32610ed 16654
d88897ea 16655 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16656
16657 spec->num_mux_defs = 1;
61b9b9b1 16658 spec->input_mux = &spec->private_imux[0];
f32610ed 16659
776e184e
TI
16660 err = alc_auto_add_mic_boost(codec);
16661 if (err < 0)
16662 return err;
16663
6227cdce 16664 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16665
f32610ed
JS
16666 return 1;
16667}
16668
16669/* additional initialization for auto-configuration model */
16670static void alc861vd_auto_init(struct hda_codec *codec)
16671{
f6c7e546 16672 struct alc_spec *spec = codec->spec;
f32610ed
JS
16673 alc861vd_auto_init_multi_out(codec);
16674 alc861vd_auto_init_hp_out(codec);
16675 alc861vd_auto_init_analog_input(codec);
f511b01c 16676 alc861vd_auto_init_input_src(codec);
f6c7e546 16677 if (spec->unsol_event)
7fb0d78f 16678 alc_inithook(codec);
f32610ed
JS
16679}
16680
f8f25ba3
TI
16681enum {
16682 ALC660VD_FIX_ASUS_GPIO1
16683};
16684
16685/* reset GPIO1 */
16686static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16687 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16688 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16689 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16690 { }
16691};
16692
16693static const struct alc_fixup alc861vd_fixups[] = {
16694 [ALC660VD_FIX_ASUS_GPIO1] = {
16695 .verbs = alc660vd_fix_asus_gpio1_verbs,
16696 },
16697};
16698
16699static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16700 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16701 {}
16702};
16703
f32610ed
JS
16704static int patch_alc861vd(struct hda_codec *codec)
16705{
16706 struct alc_spec *spec;
16707 int err, board_config;
16708
16709 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16710 if (spec == NULL)
16711 return -ENOMEM;
16712
16713 codec->spec = spec;
16714
16715 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16716 alc861vd_models,
16717 alc861vd_cfg_tbl);
16718
16719 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16720 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16721 codec->chip_name);
f32610ed
JS
16722 board_config = ALC861VD_AUTO;
16723 }
16724
7fa90e87
TI
16725 if (board_config == ALC861VD_AUTO)
16726 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 16727
f32610ed
JS
16728 if (board_config == ALC861VD_AUTO) {
16729 /* automatic parse from the BIOS config */
16730 err = alc861vd_parse_auto_config(codec);
16731 if (err < 0) {
16732 alc_free(codec);
16733 return err;
f12ab1e0 16734 } else if (!err) {
f32610ed
JS
16735 printk(KERN_INFO
16736 "hda_codec: Cannot set up configuration "
16737 "from BIOS. Using base mode...\n");
16738 board_config = ALC861VD_3ST;
16739 }
16740 }
16741
680cd536
KK
16742 err = snd_hda_attach_beep_device(codec, 0x23);
16743 if (err < 0) {
16744 alc_free(codec);
16745 return err;
16746 }
16747
f32610ed 16748 if (board_config != ALC861VD_AUTO)
e9c364c0 16749 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16750
2f893286 16751 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16752 /* always turn on EAPD */
d88897ea 16753 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16754 }
16755
f32610ed
JS
16756 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16757 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16758
f32610ed
JS
16759 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16760 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16761
dd704698
TI
16762 if (!spec->adc_nids) {
16763 spec->adc_nids = alc861vd_adc_nids;
16764 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16765 }
16766 if (!spec->capsrc_nids)
16767 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16768
b59bdf3b 16769 set_capture_mixer(codec);
45bdd1c1 16770 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16771
2134ea4f
TI
16772 spec->vmaster_nid = 0x02;
16773
7fa90e87
TI
16774 if (board_config == ALC861VD_AUTO)
16775 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16776
f32610ed
JS
16777 codec->patch_ops = alc_patch_ops;
16778
16779 if (board_config == ALC861VD_AUTO)
16780 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16781#ifdef CONFIG_SND_HDA_POWER_SAVE
16782 if (!spec->loopback.amplist)
16783 spec->loopback.amplist = alc861vd_loopbacks;
16784#endif
f32610ed
JS
16785
16786 return 0;
16787}
16788
bc9f98a9
KY
16789/*
16790 * ALC662 support
16791 *
16792 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16793 * configuration. Each pin widget can choose any input DACs and a mixer.
16794 * Each ADC is connected from a mixer of all inputs. This makes possible
16795 * 6-channel independent captures.
16796 *
16797 * In addition, an independent DAC for the multi-playback (not used in this
16798 * driver yet).
16799 */
16800#define ALC662_DIGOUT_NID 0x06
16801#define ALC662_DIGIN_NID 0x0a
16802
16803static hda_nid_t alc662_dac_nids[4] = {
16804 /* front, rear, clfe, rear_surr */
16805 0x02, 0x03, 0x04
16806};
16807
622e84cd
KY
16808static hda_nid_t alc272_dac_nids[2] = {
16809 0x02, 0x03
16810};
16811
b59bdf3b 16812static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16813 /* ADC1-2 */
b59bdf3b 16814 0x09, 0x08
bc9f98a9 16815};
e1406348 16816
622e84cd
KY
16817static hda_nid_t alc272_adc_nids[1] = {
16818 /* ADC1-2 */
16819 0x08,
16820};
16821
b59bdf3b 16822static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16823static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16824
e1406348 16825
bc9f98a9
KY
16826/* input MUX */
16827/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16828static struct hda_input_mux alc662_capture_source = {
16829 .num_items = 4,
16830 .items = {
16831 { "Mic", 0x0 },
16832 { "Front Mic", 0x1 },
16833 { "Line", 0x2 },
16834 { "CD", 0x4 },
16835 },
16836};
16837
16838static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16839 .num_items = 2,
16840 .items = {
16841 { "Mic", 0x1 },
16842 { "Line", 0x2 },
16843 },
16844};
291702f0 16845
6dda9f4a
KY
16846static struct hda_input_mux alc663_capture_source = {
16847 .num_items = 3,
16848 .items = {
16849 { "Mic", 0x0 },
16850 { "Front Mic", 0x1 },
16851 { "Line", 0x2 },
16852 },
16853};
16854
4f5d1706 16855#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16856static struct hda_input_mux alc272_nc10_capture_source = {
16857 .num_items = 16,
16858 .items = {
16859 { "Autoselect Mic", 0x0 },
16860 { "Internal Mic", 0x1 },
16861 { "In-0x02", 0x2 },
16862 { "In-0x03", 0x3 },
16863 { "In-0x04", 0x4 },
16864 { "In-0x05", 0x5 },
16865 { "In-0x06", 0x6 },
16866 { "In-0x07", 0x7 },
16867 { "In-0x08", 0x8 },
16868 { "In-0x09", 0x9 },
16869 { "In-0x0a", 0x0a },
16870 { "In-0x0b", 0x0b },
16871 { "In-0x0c", 0x0c },
16872 { "In-0x0d", 0x0d },
16873 { "In-0x0e", 0x0e },
16874 { "In-0x0f", 0x0f },
16875 },
16876};
16877#endif
16878
bc9f98a9
KY
16879/*
16880 * 2ch mode
16881 */
16882static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16883 { 2, NULL }
16884};
16885
16886/*
16887 * 2ch mode
16888 */
16889static struct hda_verb alc662_3ST_ch2_init[] = {
16890 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16891 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16892 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16893 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16894 { } /* end */
16895};
16896
16897/*
16898 * 6ch mode
16899 */
16900static struct hda_verb alc662_3ST_ch6_init[] = {
16901 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16902 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16903 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16904 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16905 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16906 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16907 { } /* end */
16908};
16909
16910static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16911 { 2, alc662_3ST_ch2_init },
16912 { 6, alc662_3ST_ch6_init },
16913};
16914
16915/*
16916 * 2ch mode
16917 */
16918static struct hda_verb alc662_sixstack_ch6_init[] = {
16919 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16920 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16921 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16922 { } /* end */
16923};
16924
16925/*
16926 * 6ch mode
16927 */
16928static struct hda_verb alc662_sixstack_ch8_init[] = {
16929 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16930 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16931 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16932 { } /* end */
16933};
16934
16935static struct hda_channel_mode alc662_5stack_modes[2] = {
16936 { 2, alc662_sixstack_ch6_init },
16937 { 6, alc662_sixstack_ch8_init },
16938};
16939
16940/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16941 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16942 */
16943
16944static struct snd_kcontrol_new alc662_base_mixer[] = {
16945 /* output mixer control */
16946 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16947 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16948 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16949 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16950 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16951 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16952 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16953 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16954 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16955
16956 /*Input mixer control */
16957 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16958 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16959 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16960 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16961 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16962 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16963 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16964 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16965 { } /* end */
16966};
16967
16968static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16969 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16970 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
16971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16972 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16973 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16978 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16979 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16980 { } /* end */
16981};
16982
16983static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16984 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16985 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16986 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 16987 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16988 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16989 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16990 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16991 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17001 { } /* end */
17002};
17003
17004static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17005 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17006 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17007 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17008 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17014 { } /* end */
17015};
17016
291702f0 17017static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17018 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17019 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17020
17021 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17022 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17023 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17024
17025 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17026 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17027 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17028 { } /* end */
17029};
17030
8c427226 17031static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17032 ALC262_HIPPO_MASTER_SWITCH,
17033 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17034 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17035 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17036 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17037 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17039 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17041 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17042 { } /* end */
17043};
17044
f1d4e28b
KY
17045static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17046 .ops = &snd_hda_bind_vol,
17047 .values = {
17048 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17049 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17050 0
17051 },
17052};
17053
17054static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17055 .ops = &snd_hda_bind_sw,
17056 .values = {
17057 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17058 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17059 0
17060 },
17061};
17062
6dda9f4a 17063static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17064 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17065 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17066 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17067 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17068 { } /* end */
17069};
17070
17071static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17072 .ops = &snd_hda_bind_sw,
17073 .values = {
17074 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17075 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17076 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17077 0
17078 },
17079};
17080
17081static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17082 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17083 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17086 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17087 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17088
17089 { } /* end */
17090};
17091
17092static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17093 .ops = &snd_hda_bind_sw,
17094 .values = {
17095 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17096 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17097 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17098 0
17099 },
17100};
17101
17102static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17103 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17104 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17107 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17108 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17109 { } /* end */
17110};
17111
17112static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17113 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17114 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17118 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17119 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17120 { } /* end */
17121};
17122
17123static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17124 .ops = &snd_hda_bind_vol,
17125 .values = {
17126 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17127 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17128 0
17129 },
17130};
17131
17132static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17133 .ops = &snd_hda_bind_sw,
17134 .values = {
17135 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17136 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17137 0
17138 },
17139};
17140
17141static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17142 HDA_BIND_VOL("Master Playback Volume",
17143 &alc663_asus_two_bind_master_vol),
17144 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17145 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17148 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17149 { } /* end */
17150};
17151
17152static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17153 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17154 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17155 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17156 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17159 { } /* end */
17160};
17161
17162static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17163 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17164 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17165 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17166 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17167 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17168
17169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17171 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17172 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17173 { } /* end */
17174};
17175
17176static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17177 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17178 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17179 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17180
17181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17182 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17183 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17184 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17187 { } /* end */
17188};
17189
ebb83eeb
KY
17190static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17191 .ops = &snd_hda_bind_sw,
17192 .values = {
17193 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17194 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17195 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17196 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17197 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17198 0
17199 },
17200};
17201
17202static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17203 .ops = &snd_hda_bind_sw,
17204 .values = {
17205 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17206 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17207 0
17208 },
17209};
17210
17211static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17212 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17213 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17214 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17215 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17216 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17217 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17218 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17221 { } /* end */
17222};
17223
17224static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17225 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17226 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17227 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17228 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17229 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17232 { } /* end */
17233};
17234
17235
bc9f98a9
KY
17236static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17237 {
17238 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17239 .name = "Channel Mode",
17240 .info = alc_ch_mode_info,
17241 .get = alc_ch_mode_get,
17242 .put = alc_ch_mode_put,
17243 },
17244 { } /* end */
17245};
17246
17247static struct hda_verb alc662_init_verbs[] = {
17248 /* ADC: mute amp left and right */
17249 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17250 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17251
b60dd394
KY
17252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17255 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17256 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17258
17259 /* Front Pin: output 0 (0x0c) */
17260 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17261 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17262
17263 /* Rear Pin: output 1 (0x0d) */
17264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17266
17267 /* CLFE Pin: output 2 (0x0e) */
17268 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17269 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17270
17271 /* Mic (rear) pin: input vref at 80% */
17272 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17273 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17274 /* Front Mic pin: input vref at 80% */
17275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17276 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17277 /* Line In pin: input */
17278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17279 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17280 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17281 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17282 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17283 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17284 /* CD pin widget for input */
17285 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17286
17287 /* FIXME: use matrix-type input source selection */
17288 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17289 /* Input mixer */
17290 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17291 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17292
17293 /* always trun on EAPD */
17294 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17295 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17296
bc9f98a9
KY
17297 { }
17298};
17299
cec27c89
KY
17300static struct hda_verb alc663_init_verbs[] = {
17301 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17302 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17303 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17304 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17305 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17307 { }
17308};
17309
17310static struct hda_verb alc272_init_verbs[] = {
17311 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17312 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17313 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17314 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17315 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17316 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17318 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17319 { }
17320};
17321
bc9f98a9
KY
17322static struct hda_verb alc662_sue_init_verbs[] = {
17323 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17324 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17325 {}
17326};
17327
17328static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17329 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17330 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17331 {}
bc9f98a9
KY
17332};
17333
8c427226
KY
17334/* Set Unsolicited Event*/
17335static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17336 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17337 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17338 {}
17339};
17340
6dda9f4a 17341static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17343 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17344 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17345 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17346 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17349 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17350 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17351 {}
17352};
17353
17354static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17355 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17356 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17357 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17358 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17360 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17361 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17362 {}
17363};
17364
17365static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17366 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17372 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17373 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17374 {}
17375};
6dda9f4a 17376
f1d4e28b
KY
17377static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17378 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17381 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17382 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17383 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17384 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17385 {}
17386};
6dda9f4a 17387
f1d4e28b
KY
17388static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17389 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17390 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17391 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17392 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17395 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17398 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17399 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17400 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17401 {}
17402};
17403
17404static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17405 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17407 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17408 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17409 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17410 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17411 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17414 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17415 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17416 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17417 {}
17418};
17419
17420static struct hda_verb alc663_g71v_init_verbs[] = {
17421 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17422 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17423 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17424
17425 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17426 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17427 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17428
17429 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17430 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17431 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17432 {}
17433};
17434
17435static struct hda_verb alc663_g50v_init_verbs[] = {
17436 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17437 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17438 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17439
17440 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17441 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17442 {}
17443};
17444
f1d4e28b
KY
17445static struct hda_verb alc662_ecs_init_verbs[] = {
17446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17447 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17448 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17449 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17450 {}
17451};
17452
622e84cd
KY
17453static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17454 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17455 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17457 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17458 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17459 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17460 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17462 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17463 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17464 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17465 {}
17466};
17467
17468static struct hda_verb alc272_dell_init_verbs[] = {
17469 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17470 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17471 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17472 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17473 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17474 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17475 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17478 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17479 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17480 {}
17481};
17482
ebb83eeb
KY
17483static struct hda_verb alc663_mode7_init_verbs[] = {
17484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17485 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17486 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17487 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17488 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17489 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17490 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17491 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17492 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17493 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17496 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17497 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17498 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17499 {}
17500};
17501
17502static struct hda_verb alc663_mode8_init_verbs[] = {
17503 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17504 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17505 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17506 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17507 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17508 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17509 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17510 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17511 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17512 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17513 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17514 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17515 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17516 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17517 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17518 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17519 {}
17520};
17521
f1d4e28b
KY
17522static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17523 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17524 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17525 { } /* end */
17526};
17527
622e84cd
KY
17528static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17529 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17530 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17531 { } /* end */
17532};
17533
bc9f98a9
KY
17534static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17535{
17536 unsigned int present;
f12ab1e0 17537 unsigned char bits;
bc9f98a9 17538
864f92be 17539 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17540 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17541
47fd830a
TI
17542 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17543 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17544}
17545
17546static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17547{
17548 unsigned int present;
f12ab1e0 17549 unsigned char bits;
bc9f98a9 17550
864f92be 17551 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17552 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17553
47fd830a
TI
17554 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17555 HDA_AMP_MUTE, bits);
17556 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17557 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17558}
17559
17560static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17561 unsigned int res)
17562{
17563 if ((res >> 26) == ALC880_HP_EVENT)
17564 alc662_lenovo_101e_all_automute(codec);
17565 if ((res >> 26) == ALC880_FRONT_EVENT)
17566 alc662_lenovo_101e_ispeaker_automute(codec);
17567}
17568
291702f0
KY
17569/* unsolicited event for HP jack sensing */
17570static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17571 unsigned int res)
17572{
291702f0 17573 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17574 alc_mic_automute(codec);
42171c17
TI
17575 else
17576 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17577}
17578
4f5d1706
TI
17579static void alc662_eeepc_setup(struct hda_codec *codec)
17580{
17581 struct alc_spec *spec = codec->spec;
17582
17583 alc262_hippo1_setup(codec);
17584 spec->ext_mic.pin = 0x18;
17585 spec->ext_mic.mux_idx = 0;
17586 spec->int_mic.pin = 0x19;
17587 spec->int_mic.mux_idx = 1;
17588 spec->auto_mic = 1;
17589}
17590
291702f0
KY
17591static void alc662_eeepc_inithook(struct hda_codec *codec)
17592{
4f5d1706
TI
17593 alc262_hippo_automute(codec);
17594 alc_mic_automute(codec);
291702f0
KY
17595}
17596
4f5d1706 17597static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17598{
42171c17
TI
17599 struct alc_spec *spec = codec->spec;
17600
17601 spec->autocfg.hp_pins[0] = 0x14;
17602 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17603}
17604
4f5d1706
TI
17605#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17606
6dda9f4a
KY
17607static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17608{
17609 unsigned int present;
17610 unsigned char bits;
17611
864f92be 17612 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17613 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17614 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17615 HDA_AMP_MUTE, bits);
f1d4e28b 17616 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17617 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17618}
17619
17620static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17621{
17622 unsigned int present;
17623 unsigned char bits;
17624
864f92be 17625 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17626 bits = present ? HDA_AMP_MUTE : 0;
17627 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17628 HDA_AMP_MUTE, bits);
f1d4e28b 17629 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17630 HDA_AMP_MUTE, bits);
f1d4e28b 17631 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17632 HDA_AMP_MUTE, bits);
f1d4e28b 17633 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17634 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17635}
17636
17637static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17638{
17639 unsigned int present;
17640 unsigned char bits;
17641
864f92be 17642 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17643 bits = present ? HDA_AMP_MUTE : 0;
17644 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17645 HDA_AMP_MUTE, bits);
f1d4e28b 17646 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17647 HDA_AMP_MUTE, bits);
f1d4e28b 17648 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17649 HDA_AMP_MUTE, bits);
f1d4e28b 17650 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17651 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17652}
17653
17654static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17655{
17656 unsigned int present;
17657 unsigned char bits;
17658
864f92be 17659 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17660 bits = present ? 0 : PIN_OUT;
17661 snd_hda_codec_write(codec, 0x14, 0,
17662 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17663}
17664
17665static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17666{
17667 unsigned int present1, present2;
17668
864f92be
WF
17669 present1 = snd_hda_jack_detect(codec, 0x21);
17670 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17671
17672 if (present1 || present2) {
17673 snd_hda_codec_write_cache(codec, 0x14, 0,
17674 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17675 } else {
17676 snd_hda_codec_write_cache(codec, 0x14, 0,
17677 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17678 }
17679}
17680
17681static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17682{
17683 unsigned int present1, present2;
17684
864f92be
WF
17685 present1 = snd_hda_jack_detect(codec, 0x1b);
17686 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17687
17688 if (present1 || present2) {
17689 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17690 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17691 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17692 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17693 } else {
17694 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17695 HDA_AMP_MUTE, 0);
f1d4e28b 17696 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17697 HDA_AMP_MUTE, 0);
f1d4e28b 17698 }
6dda9f4a
KY
17699}
17700
ebb83eeb
KY
17701static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17702{
17703 unsigned int present1, present2;
17704
17705 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17706 AC_VERB_GET_PIN_SENSE, 0)
17707 & AC_PINSENSE_PRESENCE;
17708 present2 = snd_hda_codec_read(codec, 0x21, 0,
17709 AC_VERB_GET_PIN_SENSE, 0)
17710 & AC_PINSENSE_PRESENCE;
17711
17712 if (present1 || present2) {
17713 snd_hda_codec_write_cache(codec, 0x14, 0,
17714 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17715 snd_hda_codec_write_cache(codec, 0x17, 0,
17716 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17717 } else {
17718 snd_hda_codec_write_cache(codec, 0x14, 0,
17719 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17720 snd_hda_codec_write_cache(codec, 0x17, 0,
17721 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17722 }
17723}
17724
17725static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17726{
17727 unsigned int present1, present2;
17728
17729 present1 = snd_hda_codec_read(codec, 0x21, 0,
17730 AC_VERB_GET_PIN_SENSE, 0)
17731 & AC_PINSENSE_PRESENCE;
17732 present2 = snd_hda_codec_read(codec, 0x15, 0,
17733 AC_VERB_GET_PIN_SENSE, 0)
17734 & AC_PINSENSE_PRESENCE;
17735
17736 if (present1 || present2) {
17737 snd_hda_codec_write_cache(codec, 0x14, 0,
17738 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17739 snd_hda_codec_write_cache(codec, 0x17, 0,
17740 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17741 } else {
17742 snd_hda_codec_write_cache(codec, 0x14, 0,
17743 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17744 snd_hda_codec_write_cache(codec, 0x17, 0,
17745 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17746 }
17747}
17748
6dda9f4a
KY
17749static void alc663_m51va_unsol_event(struct hda_codec *codec,
17750 unsigned int res)
17751{
17752 switch (res >> 26) {
17753 case ALC880_HP_EVENT:
17754 alc663_m51va_speaker_automute(codec);
17755 break;
17756 case ALC880_MIC_EVENT:
4f5d1706 17757 alc_mic_automute(codec);
6dda9f4a
KY
17758 break;
17759 }
17760}
17761
4f5d1706
TI
17762static void alc663_m51va_setup(struct hda_codec *codec)
17763{
17764 struct alc_spec *spec = codec->spec;
17765 spec->ext_mic.pin = 0x18;
17766 spec->ext_mic.mux_idx = 0;
17767 spec->int_mic.pin = 0x12;
ebb83eeb 17768 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17769 spec->auto_mic = 1;
17770}
17771
6dda9f4a
KY
17772static void alc663_m51va_inithook(struct hda_codec *codec)
17773{
17774 alc663_m51va_speaker_automute(codec);
4f5d1706 17775 alc_mic_automute(codec);
6dda9f4a
KY
17776}
17777
f1d4e28b 17778/* ***************** Mode1 ******************************/
4f5d1706 17779#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17780
17781static void alc663_mode1_setup(struct hda_codec *codec)
17782{
17783 struct alc_spec *spec = codec->spec;
17784 spec->ext_mic.pin = 0x18;
17785 spec->ext_mic.mux_idx = 0;
17786 spec->int_mic.pin = 0x19;
17787 spec->int_mic.mux_idx = 1;
17788 spec->auto_mic = 1;
17789}
17790
4f5d1706 17791#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17792
f1d4e28b
KY
17793/* ***************** Mode2 ******************************/
17794static void alc662_mode2_unsol_event(struct hda_codec *codec,
17795 unsigned int res)
17796{
17797 switch (res >> 26) {
17798 case ALC880_HP_EVENT:
17799 alc662_f5z_speaker_automute(codec);
17800 break;
17801 case ALC880_MIC_EVENT:
4f5d1706 17802 alc_mic_automute(codec);
f1d4e28b
KY
17803 break;
17804 }
17805}
17806
ebb83eeb 17807#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17808
f1d4e28b
KY
17809static void alc662_mode2_inithook(struct hda_codec *codec)
17810{
17811 alc662_f5z_speaker_automute(codec);
4f5d1706 17812 alc_mic_automute(codec);
f1d4e28b
KY
17813}
17814/* ***************** Mode3 ******************************/
17815static void alc663_mode3_unsol_event(struct hda_codec *codec,
17816 unsigned int res)
17817{
17818 switch (res >> 26) {
17819 case ALC880_HP_EVENT:
17820 alc663_two_hp_m1_speaker_automute(codec);
17821 break;
17822 case ALC880_MIC_EVENT:
4f5d1706 17823 alc_mic_automute(codec);
f1d4e28b
KY
17824 break;
17825 }
17826}
17827
ebb83eeb 17828#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17829
f1d4e28b
KY
17830static void alc663_mode3_inithook(struct hda_codec *codec)
17831{
17832 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17833 alc_mic_automute(codec);
f1d4e28b
KY
17834}
17835/* ***************** Mode4 ******************************/
17836static void alc663_mode4_unsol_event(struct hda_codec *codec,
17837 unsigned int res)
17838{
17839 switch (res >> 26) {
17840 case ALC880_HP_EVENT:
17841 alc663_21jd_two_speaker_automute(codec);
17842 break;
17843 case ALC880_MIC_EVENT:
4f5d1706 17844 alc_mic_automute(codec);
f1d4e28b
KY
17845 break;
17846 }
17847}
17848
ebb83eeb 17849#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17850
f1d4e28b
KY
17851static void alc663_mode4_inithook(struct hda_codec *codec)
17852{
17853 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17854 alc_mic_automute(codec);
f1d4e28b
KY
17855}
17856/* ***************** Mode5 ******************************/
17857static void alc663_mode5_unsol_event(struct hda_codec *codec,
17858 unsigned int res)
17859{
17860 switch (res >> 26) {
17861 case ALC880_HP_EVENT:
17862 alc663_15jd_two_speaker_automute(codec);
17863 break;
17864 case ALC880_MIC_EVENT:
4f5d1706 17865 alc_mic_automute(codec);
f1d4e28b
KY
17866 break;
17867 }
17868}
17869
ebb83eeb 17870#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17871
f1d4e28b
KY
17872static void alc663_mode5_inithook(struct hda_codec *codec)
17873{
17874 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17875 alc_mic_automute(codec);
f1d4e28b
KY
17876}
17877/* ***************** Mode6 ******************************/
17878static void alc663_mode6_unsol_event(struct hda_codec *codec,
17879 unsigned int res)
17880{
17881 switch (res >> 26) {
17882 case ALC880_HP_EVENT:
17883 alc663_two_hp_m2_speaker_automute(codec);
17884 break;
17885 case ALC880_MIC_EVENT:
4f5d1706 17886 alc_mic_automute(codec);
f1d4e28b
KY
17887 break;
17888 }
17889}
17890
ebb83eeb 17891#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17892
f1d4e28b
KY
17893static void alc663_mode6_inithook(struct hda_codec *codec)
17894{
17895 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17896 alc_mic_automute(codec);
f1d4e28b
KY
17897}
17898
ebb83eeb
KY
17899/* ***************** Mode7 ******************************/
17900static void alc663_mode7_unsol_event(struct hda_codec *codec,
17901 unsigned int res)
17902{
17903 switch (res >> 26) {
17904 case ALC880_HP_EVENT:
17905 alc663_two_hp_m7_speaker_automute(codec);
17906 break;
17907 case ALC880_MIC_EVENT:
17908 alc_mic_automute(codec);
17909 break;
17910 }
17911}
17912
17913#define alc663_mode7_setup alc663_mode1_setup
17914
17915static void alc663_mode7_inithook(struct hda_codec *codec)
17916{
17917 alc663_two_hp_m7_speaker_automute(codec);
17918 alc_mic_automute(codec);
17919}
17920
17921/* ***************** Mode8 ******************************/
17922static void alc663_mode8_unsol_event(struct hda_codec *codec,
17923 unsigned int res)
17924{
17925 switch (res >> 26) {
17926 case ALC880_HP_EVENT:
17927 alc663_two_hp_m8_speaker_automute(codec);
17928 break;
17929 case ALC880_MIC_EVENT:
17930 alc_mic_automute(codec);
17931 break;
17932 }
17933}
17934
17935#define alc663_mode8_setup alc663_m51va_setup
17936
17937static void alc663_mode8_inithook(struct hda_codec *codec)
17938{
17939 alc663_two_hp_m8_speaker_automute(codec);
17940 alc_mic_automute(codec);
17941}
17942
6dda9f4a
KY
17943static void alc663_g71v_hp_automute(struct hda_codec *codec)
17944{
17945 unsigned int present;
17946 unsigned char bits;
17947
864f92be 17948 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17949 bits = present ? HDA_AMP_MUTE : 0;
17950 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17951 HDA_AMP_MUTE, bits);
17952 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17953 HDA_AMP_MUTE, bits);
17954}
17955
17956static void alc663_g71v_front_automute(struct hda_codec *codec)
17957{
17958 unsigned int present;
17959 unsigned char bits;
17960
864f92be 17961 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17962 bits = present ? HDA_AMP_MUTE : 0;
17963 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17964 HDA_AMP_MUTE, bits);
17965}
17966
17967static void alc663_g71v_unsol_event(struct hda_codec *codec,
17968 unsigned int res)
17969{
17970 switch (res >> 26) {
17971 case ALC880_HP_EVENT:
17972 alc663_g71v_hp_automute(codec);
17973 break;
17974 case ALC880_FRONT_EVENT:
17975 alc663_g71v_front_automute(codec);
17976 break;
17977 case ALC880_MIC_EVENT:
4f5d1706 17978 alc_mic_automute(codec);
6dda9f4a
KY
17979 break;
17980 }
17981}
17982
4f5d1706
TI
17983#define alc663_g71v_setup alc663_m51va_setup
17984
6dda9f4a
KY
17985static void alc663_g71v_inithook(struct hda_codec *codec)
17986{
17987 alc663_g71v_front_automute(codec);
17988 alc663_g71v_hp_automute(codec);
4f5d1706 17989 alc_mic_automute(codec);
6dda9f4a
KY
17990}
17991
17992static void alc663_g50v_unsol_event(struct hda_codec *codec,
17993 unsigned int res)
17994{
17995 switch (res >> 26) {
17996 case ALC880_HP_EVENT:
17997 alc663_m51va_speaker_automute(codec);
17998 break;
17999 case ALC880_MIC_EVENT:
4f5d1706 18000 alc_mic_automute(codec);
6dda9f4a
KY
18001 break;
18002 }
18003}
18004
4f5d1706
TI
18005#define alc663_g50v_setup alc663_m51va_setup
18006
6dda9f4a
KY
18007static void alc663_g50v_inithook(struct hda_codec *codec)
18008{
18009 alc663_m51va_speaker_automute(codec);
4f5d1706 18010 alc_mic_automute(codec);
6dda9f4a
KY
18011}
18012
f1d4e28b
KY
18013static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18014 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18015 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18016
18017 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18018 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18019 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18020
18021 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18022 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18023 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18024 { } /* end */
18025};
18026
9541ba1d
CP
18027static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18028 /* Master Playback automatically created from Speaker and Headphone */
18029 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18030 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18031 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18032 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18033
18034 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18035 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18036 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18037
18038 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18039 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18040 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18041 { } /* end */
18042};
18043
cb53c626
TI
18044#ifdef CONFIG_SND_HDA_POWER_SAVE
18045#define alc662_loopbacks alc880_loopbacks
18046#endif
18047
bc9f98a9 18048
def319f9 18049/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18050#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18051#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18052#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18053#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18054
18055/*
18056 * configuration and preset
18057 */
18058static const char *alc662_models[ALC662_MODEL_LAST] = {
18059 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18060 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18061 [ALC662_3ST_6ch] = "3stack-6ch",
18062 [ALC662_5ST_DIG] = "6stack-dig",
18063 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18064 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18065 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18066 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18067 [ALC663_ASUS_M51VA] = "m51va",
18068 [ALC663_ASUS_G71V] = "g71v",
18069 [ALC663_ASUS_H13] = "h13",
18070 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18071 [ALC663_ASUS_MODE1] = "asus-mode1",
18072 [ALC662_ASUS_MODE2] = "asus-mode2",
18073 [ALC663_ASUS_MODE3] = "asus-mode3",
18074 [ALC663_ASUS_MODE4] = "asus-mode4",
18075 [ALC663_ASUS_MODE5] = "asus-mode5",
18076 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18077 [ALC663_ASUS_MODE7] = "asus-mode7",
18078 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18079 [ALC272_DELL] = "dell",
18080 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18081 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18082 [ALC662_AUTO] = "auto",
18083};
18084
18085static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18086 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18087 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18088 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18089 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18090 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18091 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18092 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18093 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18094 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18095 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18096 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18097 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18098 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18099 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18100 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18101 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18102 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18103 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18104 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18105 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18106 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18107 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18108 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18109 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18110 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18111 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18112 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18113 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18114 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18115 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18116 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18117 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18118 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18119 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18120 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18121 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18122 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18123 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18124 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18125 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18126 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18127 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18128 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18129 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18130 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18131 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18132 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18133 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18134 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18135 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18136 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18137 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18138 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18139 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18140 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18141 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18142 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18143 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18144 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18145 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18146 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18147 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18148 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18149 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18150 ALC662_3ST_6ch_DIG),
4dee8baa 18151 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18152 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18153 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18154 ALC662_3ST_6ch_DIG),
6227cdce 18155 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18156 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18157 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18158 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18159 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18160 ALC662_3ST_6ch_DIG),
dea0a509
TI
18161 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18162 ALC663_ASUS_H13),
bc9f98a9
KY
18163 {}
18164};
18165
18166static struct alc_config_preset alc662_presets[] = {
18167 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18168 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18169 .init_verbs = { alc662_init_verbs },
18170 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18171 .dac_nids = alc662_dac_nids,
18172 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18173 .dig_in_nid = ALC662_DIGIN_NID,
18174 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18175 .channel_mode = alc662_3ST_2ch_modes,
18176 .input_mux = &alc662_capture_source,
18177 },
18178 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18179 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18180 .init_verbs = { alc662_init_verbs },
18181 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18182 .dac_nids = alc662_dac_nids,
18183 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18184 .dig_in_nid = ALC662_DIGIN_NID,
18185 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18186 .channel_mode = alc662_3ST_6ch_modes,
18187 .need_dac_fix = 1,
18188 .input_mux = &alc662_capture_source,
f12ab1e0 18189 },
bc9f98a9 18190 [ALC662_3ST_6ch] = {
f9e336f6 18191 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18192 .init_verbs = { alc662_init_verbs },
18193 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18194 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18195 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18196 .channel_mode = alc662_3ST_6ch_modes,
18197 .need_dac_fix = 1,
18198 .input_mux = &alc662_capture_source,
f12ab1e0 18199 },
bc9f98a9 18200 [ALC662_5ST_DIG] = {
f9e336f6 18201 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18202 .init_verbs = { alc662_init_verbs },
18203 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18204 .dac_nids = alc662_dac_nids,
18205 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18206 .dig_in_nid = ALC662_DIGIN_NID,
18207 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18208 .channel_mode = alc662_5stack_modes,
18209 .input_mux = &alc662_capture_source,
18210 },
18211 [ALC662_LENOVO_101E] = {
f9e336f6 18212 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18213 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18214 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18215 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18216 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18217 .channel_mode = alc662_3ST_2ch_modes,
18218 .input_mux = &alc662_lenovo_101e_capture_source,
18219 .unsol_event = alc662_lenovo_101e_unsol_event,
18220 .init_hook = alc662_lenovo_101e_all_automute,
18221 },
291702f0 18222 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18223 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18224 .init_verbs = { alc662_init_verbs,
18225 alc662_eeepc_sue_init_verbs },
18226 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18227 .dac_nids = alc662_dac_nids,
291702f0
KY
18228 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18229 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18230 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18231 .setup = alc662_eeepc_setup,
291702f0
KY
18232 .init_hook = alc662_eeepc_inithook,
18233 },
8c427226 18234 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18235 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18236 alc662_chmode_mixer },
18237 .init_verbs = { alc662_init_verbs,
18238 alc662_eeepc_ep20_sue_init_verbs },
18239 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18240 .dac_nids = alc662_dac_nids,
8c427226
KY
18241 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18242 .channel_mode = alc662_3ST_6ch_modes,
18243 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18244 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18245 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18246 .init_hook = alc662_eeepc_ep20_inithook,
18247 },
f1d4e28b 18248 [ALC662_ECS] = {
f9e336f6 18249 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18250 .init_verbs = { alc662_init_verbs,
18251 alc662_ecs_init_verbs },
18252 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18253 .dac_nids = alc662_dac_nids,
18254 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18255 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18256 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18257 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18258 .init_hook = alc662_eeepc_inithook,
18259 },
6dda9f4a 18260 [ALC663_ASUS_M51VA] = {
f9e336f6 18261 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18262 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18263 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18264 .dac_nids = alc662_dac_nids,
18265 .dig_out_nid = ALC662_DIGOUT_NID,
18266 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18267 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18268 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18269 .setup = alc663_m51va_setup,
6dda9f4a
KY
18270 .init_hook = alc663_m51va_inithook,
18271 },
18272 [ALC663_ASUS_G71V] = {
f9e336f6 18273 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18274 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18275 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18276 .dac_nids = alc662_dac_nids,
18277 .dig_out_nid = ALC662_DIGOUT_NID,
18278 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18279 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18280 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18281 .setup = alc663_g71v_setup,
6dda9f4a
KY
18282 .init_hook = alc663_g71v_inithook,
18283 },
18284 [ALC663_ASUS_H13] = {
f9e336f6 18285 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18286 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18287 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18288 .dac_nids = alc662_dac_nids,
18289 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18290 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18291 .unsol_event = alc663_m51va_unsol_event,
18292 .init_hook = alc663_m51va_inithook,
18293 },
18294 [ALC663_ASUS_G50V] = {
f9e336f6 18295 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18296 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18297 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18298 .dac_nids = alc662_dac_nids,
18299 .dig_out_nid = ALC662_DIGOUT_NID,
18300 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18301 .channel_mode = alc662_3ST_6ch_modes,
18302 .input_mux = &alc663_capture_source,
18303 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18304 .setup = alc663_g50v_setup,
6dda9f4a
KY
18305 .init_hook = alc663_g50v_inithook,
18306 },
f1d4e28b 18307 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18308 .mixers = { alc663_m51va_mixer },
18309 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18310 .init_verbs = { alc662_init_verbs,
18311 alc663_21jd_amic_init_verbs },
18312 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18313 .hp_nid = 0x03,
18314 .dac_nids = alc662_dac_nids,
18315 .dig_out_nid = ALC662_DIGOUT_NID,
18316 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18317 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18318 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18319 .setup = alc663_mode1_setup,
f1d4e28b
KY
18320 .init_hook = alc663_mode1_inithook,
18321 },
18322 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18323 .mixers = { alc662_1bjd_mixer },
18324 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18325 .init_verbs = { alc662_init_verbs,
18326 alc662_1bjd_amic_init_verbs },
18327 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18328 .dac_nids = alc662_dac_nids,
18329 .dig_out_nid = ALC662_DIGOUT_NID,
18330 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18331 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18332 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18333 .setup = alc662_mode2_setup,
f1d4e28b
KY
18334 .init_hook = alc662_mode2_inithook,
18335 },
18336 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18337 .mixers = { alc663_two_hp_m1_mixer },
18338 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18339 .init_verbs = { alc662_init_verbs,
18340 alc663_two_hp_amic_m1_init_verbs },
18341 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18342 .hp_nid = 0x03,
18343 .dac_nids = alc662_dac_nids,
18344 .dig_out_nid = ALC662_DIGOUT_NID,
18345 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18346 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18347 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18348 .setup = alc663_mode3_setup,
f1d4e28b
KY
18349 .init_hook = alc663_mode3_inithook,
18350 },
18351 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18352 .mixers = { alc663_asus_21jd_clfe_mixer },
18353 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18354 .init_verbs = { alc662_init_verbs,
18355 alc663_21jd_amic_init_verbs},
18356 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18357 .hp_nid = 0x03,
18358 .dac_nids = alc662_dac_nids,
18359 .dig_out_nid = ALC662_DIGOUT_NID,
18360 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18361 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18362 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18363 .setup = alc663_mode4_setup,
f1d4e28b
KY
18364 .init_hook = alc663_mode4_inithook,
18365 },
18366 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18367 .mixers = { alc663_asus_15jd_clfe_mixer },
18368 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18369 .init_verbs = { alc662_init_verbs,
18370 alc663_15jd_amic_init_verbs },
18371 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18372 .hp_nid = 0x03,
18373 .dac_nids = alc662_dac_nids,
18374 .dig_out_nid = ALC662_DIGOUT_NID,
18375 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18376 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18377 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18378 .setup = alc663_mode5_setup,
f1d4e28b
KY
18379 .init_hook = alc663_mode5_inithook,
18380 },
18381 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18382 .mixers = { alc663_two_hp_m2_mixer },
18383 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18384 .init_verbs = { alc662_init_verbs,
18385 alc663_two_hp_amic_m2_init_verbs },
18386 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18387 .hp_nid = 0x03,
18388 .dac_nids = alc662_dac_nids,
18389 .dig_out_nid = ALC662_DIGOUT_NID,
18390 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18391 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18392 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18393 .setup = alc663_mode6_setup,
f1d4e28b
KY
18394 .init_hook = alc663_mode6_inithook,
18395 },
ebb83eeb
KY
18396 [ALC663_ASUS_MODE7] = {
18397 .mixers = { alc663_mode7_mixer },
18398 .cap_mixer = alc662_auto_capture_mixer,
18399 .init_verbs = { alc662_init_verbs,
18400 alc663_mode7_init_verbs },
18401 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18402 .hp_nid = 0x03,
18403 .dac_nids = alc662_dac_nids,
18404 .dig_out_nid = ALC662_DIGOUT_NID,
18405 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18406 .channel_mode = alc662_3ST_2ch_modes,
18407 .unsol_event = alc663_mode7_unsol_event,
18408 .setup = alc663_mode7_setup,
18409 .init_hook = alc663_mode7_inithook,
18410 },
18411 [ALC663_ASUS_MODE8] = {
18412 .mixers = { alc663_mode8_mixer },
18413 .cap_mixer = alc662_auto_capture_mixer,
18414 .init_verbs = { alc662_init_verbs,
18415 alc663_mode8_init_verbs },
18416 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18417 .hp_nid = 0x03,
18418 .dac_nids = alc662_dac_nids,
18419 .dig_out_nid = ALC662_DIGOUT_NID,
18420 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18421 .channel_mode = alc662_3ST_2ch_modes,
18422 .unsol_event = alc663_mode8_unsol_event,
18423 .setup = alc663_mode8_setup,
18424 .init_hook = alc663_mode8_inithook,
18425 },
622e84cd
KY
18426 [ALC272_DELL] = {
18427 .mixers = { alc663_m51va_mixer },
18428 .cap_mixer = alc272_auto_capture_mixer,
18429 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18430 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18431 .dac_nids = alc662_dac_nids,
18432 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18433 .adc_nids = alc272_adc_nids,
18434 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18435 .capsrc_nids = alc272_capsrc_nids,
18436 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18437 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18438 .setup = alc663_m51va_setup,
622e84cd
KY
18439 .init_hook = alc663_m51va_inithook,
18440 },
18441 [ALC272_DELL_ZM1] = {
18442 .mixers = { alc663_m51va_mixer },
18443 .cap_mixer = alc662_auto_capture_mixer,
18444 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18445 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18446 .dac_nids = alc662_dac_nids,
18447 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18448 .adc_nids = alc662_adc_nids,
b59bdf3b 18449 .num_adc_nids = 1,
622e84cd
KY
18450 .capsrc_nids = alc662_capsrc_nids,
18451 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18452 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18453 .setup = alc663_m51va_setup,
622e84cd
KY
18454 .init_hook = alc663_m51va_inithook,
18455 },
9541ba1d
CP
18456 [ALC272_SAMSUNG_NC10] = {
18457 .mixers = { alc272_nc10_mixer },
18458 .init_verbs = { alc662_init_verbs,
18459 alc663_21jd_amic_init_verbs },
18460 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18461 .dac_nids = alc272_dac_nids,
18462 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18463 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18464 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18465 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18466 .setup = alc663_mode4_setup,
9541ba1d
CP
18467 .init_hook = alc663_mode4_inithook,
18468 },
bc9f98a9
KY
18469};
18470
18471
18472/*
18473 * BIOS auto configuration
18474 */
18475
7085ec12
TI
18476/* convert from MIX nid to DAC */
18477static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18478{
18479 if (nid == 0x0f)
18480 return 0x02;
18481 else if (nid >= 0x0c && nid <= 0x0e)
18482 return nid - 0x0c + 0x02;
18483 else
18484 return 0;
18485}
18486
18487/* get MIX nid connected to the given pin targeted to DAC */
18488static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18489 hda_nid_t dac)
18490{
18491 hda_nid_t mix[4];
18492 int i, num;
18493
18494 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18495 for (i = 0; i < num; i++) {
18496 if (alc662_mix_to_dac(mix[i]) == dac)
18497 return mix[i];
18498 }
18499 return 0;
18500}
18501
18502/* look for an empty DAC slot */
18503static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18504{
18505 struct alc_spec *spec = codec->spec;
18506 hda_nid_t srcs[5];
18507 int i, j, num;
18508
18509 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18510 if (num < 0)
18511 return 0;
18512 for (i = 0; i < num; i++) {
18513 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18514 if (!nid)
18515 continue;
18516 for (j = 0; j < spec->multiout.num_dacs; j++)
18517 if (spec->multiout.dac_nids[j] == nid)
18518 break;
18519 if (j >= spec->multiout.num_dacs)
18520 return nid;
18521 }
18522 return 0;
18523}
18524
18525/* fill in the dac_nids table from the parsed pin configuration */
18526static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18527 const struct auto_pin_cfg *cfg)
18528{
18529 struct alc_spec *spec = codec->spec;
18530 int i;
18531 hda_nid_t dac;
18532
18533 spec->multiout.dac_nids = spec->private_dac_nids;
18534 for (i = 0; i < cfg->line_outs; i++) {
18535 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18536 if (!dac)
18537 continue;
18538 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18539 }
18540 return 0;
18541}
18542
0afe5f89 18543static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18544 hda_nid_t nid, unsigned int chs)
18545{
0afe5f89 18546 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18547 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18548}
18549
0afe5f89 18550static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18551 hda_nid_t nid, unsigned int chs)
18552{
0afe5f89 18553 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18554 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18555}
18556
18557#define alc662_add_stereo_vol(spec, pfx, nid) \
18558 alc662_add_vol_ctl(spec, pfx, nid, 3)
18559#define alc662_add_stereo_sw(spec, pfx, nid) \
18560 alc662_add_sw_ctl(spec, pfx, nid, 3)
18561
bc9f98a9 18562/* add playback controls from the parsed DAC table */
7085ec12 18563static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18564 const struct auto_pin_cfg *cfg)
18565{
7085ec12 18566 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18567 static const char *chname[4] = {
18568 "Front", "Surround", NULL /*CLFE*/, "Side"
18569 };
7085ec12 18570 hda_nid_t nid, mix;
bc9f98a9
KY
18571 int i, err;
18572
18573 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18574 nid = spec->multiout.dac_nids[i];
18575 if (!nid)
18576 continue;
18577 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18578 if (!mix)
bc9f98a9 18579 continue;
bc9f98a9
KY
18580 if (i == 2) {
18581 /* Center/LFE */
7085ec12 18582 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18583 if (err < 0)
18584 return err;
7085ec12 18585 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18586 if (err < 0)
18587 return err;
7085ec12 18588 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18589 if (err < 0)
18590 return err;
7085ec12 18591 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18592 if (err < 0)
18593 return err;
18594 } else {
0d884cb9
TI
18595 const char *pfx;
18596 if (cfg->line_outs == 1 &&
18597 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18598 if (cfg->hp_outs)
0d884cb9
TI
18599 pfx = "Speaker";
18600 else
18601 pfx = "PCM";
18602 } else
18603 pfx = chname[i];
7085ec12 18604 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18605 if (err < 0)
18606 return err;
0d884cb9
TI
18607 if (cfg->line_outs == 1 &&
18608 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18609 pfx = "Speaker";
7085ec12 18610 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18611 if (err < 0)
18612 return err;
18613 }
18614 }
18615 return 0;
18616}
18617
18618/* add playback controls for speaker and HP outputs */
7085ec12
TI
18619/* return DAC nid if any new DAC is assigned */
18620static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18621 const char *pfx)
18622{
7085ec12
TI
18623 struct alc_spec *spec = codec->spec;
18624 hda_nid_t nid, mix;
bc9f98a9 18625 int err;
bc9f98a9
KY
18626
18627 if (!pin)
18628 return 0;
7085ec12
TI
18629 nid = alc662_look_for_dac(codec, pin);
18630 if (!nid) {
7085ec12
TI
18631 /* the corresponding DAC is already occupied */
18632 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18633 return 0; /* no way */
18634 /* create a switch only */
0afe5f89 18635 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18636 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18637 }
18638
7085ec12
TI
18639 mix = alc662_dac_to_mix(codec, pin, nid);
18640 if (!mix)
18641 return 0;
18642 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18643 if (err < 0)
18644 return err;
18645 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18646 if (err < 0)
18647 return err;
18648 return nid;
bc9f98a9
KY
18649}
18650
18651/* create playback/capture controls for input pins */
05f5f477 18652#define alc662_auto_create_input_ctls \
4b7348a1 18653 alc882_auto_create_input_ctls
bc9f98a9
KY
18654
18655static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18656 hda_nid_t nid, int pin_type,
7085ec12 18657 hda_nid_t dac)
bc9f98a9 18658{
7085ec12
TI
18659 int i, num;
18660 hda_nid_t srcs[4];
18661
f6c7e546 18662 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18663 /* need the manual connection? */
7085ec12
TI
18664 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18665 if (num <= 1)
18666 return;
18667 for (i = 0; i < num; i++) {
18668 if (alc662_mix_to_dac(srcs[i]) != dac)
18669 continue;
18670 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18671 return;
bc9f98a9
KY
18672 }
18673}
18674
18675static void alc662_auto_init_multi_out(struct hda_codec *codec)
18676{
18677 struct alc_spec *spec = codec->spec;
7085ec12 18678 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18679 int i;
18680
18681 for (i = 0; i <= HDA_SIDE; i++) {
18682 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18683 if (nid)
baba8ee9 18684 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18685 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18686 }
18687}
18688
18689static void alc662_auto_init_hp_out(struct hda_codec *codec)
18690{
18691 struct alc_spec *spec = codec->spec;
18692 hda_nid_t pin;
18693
18694 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18695 if (pin)
18696 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18697 spec->multiout.hp_nid);
f6c7e546
TI
18698 pin = spec->autocfg.speaker_pins[0];
18699 if (pin)
7085ec12
TI
18700 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18701 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18702}
18703
bc9f98a9
KY
18704#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18705
18706static void alc662_auto_init_analog_input(struct hda_codec *codec)
18707{
18708 struct alc_spec *spec = codec->spec;
18709 int i;
18710
18711 for (i = 0; i < AUTO_PIN_LAST; i++) {
18712 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18713 if (alc_is_input_pin(codec, nid)) {
23f0c048 18714 alc_set_input_pin(codec, nid, i);
52ca15b7 18715 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18716 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18717 snd_hda_codec_write(codec, nid, 0,
18718 AC_VERB_SET_AMP_GAIN_MUTE,
18719 AMP_OUT_MUTE);
18720 }
18721 }
18722}
18723
f511b01c
TI
18724#define alc662_auto_init_input_src alc882_auto_init_input_src
18725
bc9f98a9
KY
18726static int alc662_parse_auto_config(struct hda_codec *codec)
18727{
18728 struct alc_spec *spec = codec->spec;
18729 int err;
18730 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18731
18732 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18733 alc662_ignore);
18734 if (err < 0)
18735 return err;
18736 if (!spec->autocfg.line_outs)
18737 return 0; /* can't find valid BIOS pin config */
18738
7085ec12 18739 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18740 if (err < 0)
18741 return err;
7085ec12 18742 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18743 if (err < 0)
18744 return err;
7085ec12 18745 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18746 spec->autocfg.speaker_pins[0],
18747 "Speaker");
18748 if (err < 0)
18749 return err;
7085ec12
TI
18750 if (err)
18751 spec->multiout.extra_out_nid[0] = err;
18752 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18753 "Headphone");
18754 if (err < 0)
18755 return err;
7085ec12
TI
18756 if (err)
18757 spec->multiout.hp_nid = err;
05f5f477 18758 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18759 if (err < 0)
bc9f98a9
KY
18760 return err;
18761
18762 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18763
0852d7a6 18764 if (spec->autocfg.dig_outs)
bc9f98a9
KY
18765 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18766
603c4019 18767 if (spec->kctls.list)
d88897ea 18768 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18769
18770 spec->num_mux_defs = 1;
61b9b9b1 18771 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18772
cec27c89
KY
18773 add_verb(spec, alc662_init_verbs);
18774 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 18775 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
18776 add_verb(spec, alc663_init_verbs);
18777
18778 if (codec->vendor_id == 0x10ec0272)
18779 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18780
18781 err = alc_auto_add_mic_boost(codec);
18782 if (err < 0)
18783 return err;
18784
6227cdce
KY
18785 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18786 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18787 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18788 else
18789 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18790
8c87286f 18791 return 1;
bc9f98a9
KY
18792}
18793
18794/* additional initialization for auto-configuration model */
18795static void alc662_auto_init(struct hda_codec *codec)
18796{
f6c7e546 18797 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18798 alc662_auto_init_multi_out(codec);
18799 alc662_auto_init_hp_out(codec);
18800 alc662_auto_init_analog_input(codec);
f511b01c 18801 alc662_auto_init_input_src(codec);
f6c7e546 18802 if (spec->unsol_event)
7fb0d78f 18803 alc_inithook(codec);
bc9f98a9
KY
18804}
18805
18806static int patch_alc662(struct hda_codec *codec)
18807{
18808 struct alc_spec *spec;
18809 int err, board_config;
18810
18811 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18812 if (!spec)
18813 return -ENOMEM;
18814
18815 codec->spec = spec;
18816
da00c244
KY
18817 alc_auto_parse_customize_define(codec);
18818
2c3bf9ab
TI
18819 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18820
c027ddcd
KY
18821 if (alc_read_coef_idx(codec, 0) == 0x8020)
18822 alc_codec_rename(codec, "ALC661");
18823 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18824 codec->bus->pci->subsystem_vendor == 0x1025 &&
18825 spec->cdefine.platform_type == 1)
18826 alc_codec_rename(codec, "ALC272X");
274693f3 18827
bc9f98a9
KY
18828 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18829 alc662_models,
18830 alc662_cfg_tbl);
18831 if (board_config < 0) {
9a11f1aa
TI
18832 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18833 codec->chip_name);
bc9f98a9
KY
18834 board_config = ALC662_AUTO;
18835 }
18836
18837 if (board_config == ALC662_AUTO) {
18838 /* automatic parse from the BIOS config */
18839 err = alc662_parse_auto_config(codec);
18840 if (err < 0) {
18841 alc_free(codec);
18842 return err;
8c87286f 18843 } else if (!err) {
bc9f98a9
KY
18844 printk(KERN_INFO
18845 "hda_codec: Cannot set up configuration "
18846 "from BIOS. Using base mode...\n");
18847 board_config = ALC662_3ST_2ch_DIG;
18848 }
18849 }
18850
dc1eae25 18851 if (has_cdefine_beep(codec)) {
8af2591d
TI
18852 err = snd_hda_attach_beep_device(codec, 0x1);
18853 if (err < 0) {
18854 alc_free(codec);
18855 return err;
18856 }
680cd536
KK
18857 }
18858
bc9f98a9 18859 if (board_config != ALC662_AUTO)
e9c364c0 18860 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18861
bc9f98a9
KY
18862 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18863 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18864
bc9f98a9
KY
18865 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18866 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18867
dd704698
TI
18868 if (!spec->adc_nids) {
18869 spec->adc_nids = alc662_adc_nids;
18870 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18871 }
18872 if (!spec->capsrc_nids)
18873 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18874
f9e336f6 18875 if (!spec->cap_mixer)
b59bdf3b 18876 set_capture_mixer(codec);
cec27c89 18877
dc1eae25 18878 if (has_cdefine_beep(codec)) {
da00c244
KY
18879 switch (codec->vendor_id) {
18880 case 0x10ec0662:
18881 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18882 break;
18883 case 0x10ec0272:
18884 case 0x10ec0663:
18885 case 0x10ec0665:
18886 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18887 break;
18888 case 0x10ec0273:
18889 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18890 break;
18891 }
cec27c89 18892 }
2134ea4f
TI
18893 spec->vmaster_nid = 0x02;
18894
bc9f98a9
KY
18895 codec->patch_ops = alc_patch_ops;
18896 if (board_config == ALC662_AUTO)
18897 spec->init_hook = alc662_auto_init;
cb53c626
TI
18898#ifdef CONFIG_SND_HDA_POWER_SAVE
18899 if (!spec->loopback.amplist)
18900 spec->loopback.amplist = alc662_loopbacks;
18901#endif
bc9f98a9
KY
18902
18903 return 0;
18904}
18905
274693f3
KY
18906static int patch_alc888(struct hda_codec *codec)
18907{
18908 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18909 kfree(codec->chip_name);
18910 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18911 if (!codec->chip_name) {
18912 alc_free(codec);
274693f3 18913 return -ENOMEM;
ac2c92e0
TI
18914 }
18915 return patch_alc662(codec);
274693f3 18916 }
ac2c92e0 18917 return patch_alc882(codec);
274693f3
KY
18918}
18919
d1eb57f4
KY
18920/*
18921 * ALC680 support
18922 */
18923#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18924#define alc680_modes alc260_modes
18925
18926static hda_nid_t alc680_dac_nids[3] = {
18927 /* Lout1, Lout2, hp */
18928 0x02, 0x03, 0x04
18929};
18930
18931static hda_nid_t alc680_adc_nids[3] = {
18932 /* ADC0-2 */
18933 /* DMIC, MIC, Line-in*/
18934 0x07, 0x08, 0x09
18935};
18936
18937static struct snd_kcontrol_new alc680_base_mixer[] = {
18938 /* output mixer control */
18939 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18940 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18941 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18942 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18943 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18944 { }
18945};
18946
18947static struct snd_kcontrol_new alc680_capture_mixer[] = {
18948 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18949 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18950 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18951 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18952 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18953 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18954 { } /* end */
18955};
18956
18957/*
18958 * generic initialization of ADC, input mixers and output mixers
18959 */
18960static struct hda_verb alc680_init_verbs[] = {
18961 /* Unmute DAC0-1 and set vol = 0 */
18962 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18963 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18964 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18965
18966 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
18967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
18968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
18969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
18970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
18971
18972 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18974 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18975 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18976 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18977 { }
18978};
18979
18980/* create input playback/capture controls for the given pin */
18981static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
18982 const char *ctlname, int idx)
18983{
18984 hda_nid_t dac;
18985 int err;
18986
18987 switch (nid) {
18988 case 0x14:
18989 dac = 0x02;
18990 break;
18991 case 0x15:
18992 dac = 0x03;
18993 break;
18994 case 0x16:
18995 dac = 0x04;
18996 break;
18997 default:
18998 return 0;
18999 }
19000 if (spec->multiout.dac_nids[0] != dac &&
19001 spec->multiout.dac_nids[1] != dac) {
19002 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19003 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19004 HDA_OUTPUT));
19005 if (err < 0)
19006 return err;
19007
19008 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19009 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19010
19011 if (err < 0)
19012 return err;
19013 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19014 }
19015
19016 return 0;
19017}
19018
19019/* add playback controls from the parsed DAC table */
19020static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19021 const struct auto_pin_cfg *cfg)
19022{
19023 hda_nid_t nid;
19024 int err;
19025
19026 spec->multiout.dac_nids = spec->private_dac_nids;
19027
19028 nid = cfg->line_out_pins[0];
19029 if (nid) {
19030 const char *name;
19031 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19032 name = "Speaker";
19033 else
19034 name = "Front";
19035 err = alc680_new_analog_output(spec, nid, name, 0);
19036 if (err < 0)
19037 return err;
19038 }
19039
19040 nid = cfg->speaker_pins[0];
19041 if (nid) {
19042 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19043 if (err < 0)
19044 return err;
19045 }
19046 nid = cfg->hp_pins[0];
19047 if (nid) {
19048 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19049 if (err < 0)
19050 return err;
19051 }
19052
19053 return 0;
19054}
19055
19056static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19057 hda_nid_t nid, int pin_type)
19058{
19059 alc_set_pin_output(codec, nid, pin_type);
19060}
19061
19062static void alc680_auto_init_multi_out(struct hda_codec *codec)
19063{
19064 struct alc_spec *spec = codec->spec;
19065 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19066 if (nid) {
19067 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19068 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19069 }
19070}
19071
19072static void alc680_auto_init_hp_out(struct hda_codec *codec)
19073{
19074 struct alc_spec *spec = codec->spec;
19075 hda_nid_t pin;
19076
19077 pin = spec->autocfg.hp_pins[0];
19078 if (pin)
19079 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19080 pin = spec->autocfg.speaker_pins[0];
19081 if (pin)
19082 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19083}
19084
19085/* pcm configuration: identical with ALC880 */
19086#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19087#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19088#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19089#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19090
19091static struct hda_input_mux alc680_capture_source = {
19092 .num_items = 1,
19093 .items = {
19094 { "Mic", 0x0 },
19095 },
19096};
19097
19098/*
19099 * BIOS auto configuration
19100 */
19101static int alc680_parse_auto_config(struct hda_codec *codec)
19102{
19103 struct alc_spec *spec = codec->spec;
19104 int err;
19105 static hda_nid_t alc680_ignore[] = { 0 };
19106
19107 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19108 alc680_ignore);
19109 if (err < 0)
19110 return err;
19111 if (!spec->autocfg.line_outs) {
19112 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19113 spec->multiout.max_channels = 2;
19114 spec->no_analog = 1;
19115 goto dig_only;
19116 }
19117 return 0; /* can't find valid BIOS pin config */
19118 }
19119 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19120 if (err < 0)
19121 return err;
19122
19123 spec->multiout.max_channels = 2;
19124
19125 dig_only:
19126 /* digital only support output */
19127 if (spec->autocfg.dig_outs) {
19128 spec->multiout.dig_out_nid = ALC680_DIGOUT_NID;
19129 spec->dig_out_type = spec->autocfg.dig_out_type[0];
19130 }
19131 if (spec->kctls.list)
19132 add_mixer(spec, spec->kctls.list);
19133
19134 add_verb(spec, alc680_init_verbs);
19135 spec->num_mux_defs = 1;
19136 spec->input_mux = &alc680_capture_source;
19137
19138 err = alc_auto_add_mic_boost(codec);
19139 if (err < 0)
19140 return err;
19141
19142 return 1;
19143}
19144
19145#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19146
19147/* init callback for auto-configuration model -- overriding the default init */
19148static void alc680_auto_init(struct hda_codec *codec)
19149{
19150 struct alc_spec *spec = codec->spec;
19151 alc680_auto_init_multi_out(codec);
19152 alc680_auto_init_hp_out(codec);
19153 alc680_auto_init_analog_input(codec);
19154 if (spec->unsol_event)
19155 alc_inithook(codec);
19156}
19157
19158/*
19159 * configuration and preset
19160 */
19161static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19162 [ALC680_BASE] = "base",
19163 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19164};
19165
19166static struct snd_pci_quirk alc680_cfg_tbl[] = {
19167 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19168 {}
19169};
19170
19171static struct alc_config_preset alc680_presets[] = {
19172 [ALC680_BASE] = {
19173 .mixers = { alc680_base_mixer },
19174 .cap_mixer = alc680_capture_mixer,
19175 .init_verbs = { alc680_init_verbs },
19176 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19177 .dac_nids = alc680_dac_nids,
19178 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19179 .adc_nids = alc680_adc_nids,
19180 .hp_nid = 0x04,
19181 .dig_out_nid = ALC680_DIGOUT_NID,
19182 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19183 .channel_mode = alc680_modes,
19184 .input_mux = &alc680_capture_source,
19185 },
19186};
19187
19188static int patch_alc680(struct hda_codec *codec)
19189{
19190 struct alc_spec *spec;
19191 int board_config;
19192 int err;
19193
19194 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19195 if (spec == NULL)
19196 return -ENOMEM;
19197
19198 codec->spec = spec;
19199
19200 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19201 alc680_models,
19202 alc680_cfg_tbl);
19203
19204 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19205 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19206 codec->chip_name);
19207 board_config = ALC680_AUTO;
19208 }
19209
19210 if (board_config == ALC680_AUTO) {
19211 /* automatic parse from the BIOS config */
19212 err = alc680_parse_auto_config(codec);
19213 if (err < 0) {
19214 alc_free(codec);
19215 return err;
19216 } else if (!err) {
19217 printk(KERN_INFO
19218 "hda_codec: Cannot set up configuration "
19219 "from BIOS. Using base mode...\n");
19220 board_config = ALC680_BASE;
19221 }
19222 }
19223
19224 if (board_config != ALC680_AUTO)
19225 setup_preset(codec, &alc680_presets[board_config]);
19226
19227 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19228 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19229 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19230 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19231
19232 if (!spec->adc_nids) {
19233 spec->adc_nids = alc680_adc_nids;
19234 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19235 }
19236
19237 if (!spec->cap_mixer)
19238 set_capture_mixer(codec);
19239
19240 spec->vmaster_nid = 0x02;
19241
19242 codec->patch_ops = alc_patch_ops;
19243 if (board_config == ALC680_AUTO)
19244 spec->init_hook = alc680_auto_init;
19245
19246 return 0;
19247}
19248
1da177e4
LT
19249/*
19250 * patch entries
19251 */
1289e9e8 19252static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19253 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19254 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19255 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19256 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19257 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19258 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19259 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19260 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19261 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19262 .patch = patch_alc861 },
f32610ed
JS
19263 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19264 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19265 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19266 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19267 .patch = patch_alc882 },
bc9f98a9
KY
19268 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19269 .patch = patch_alc662 },
6dda9f4a 19270 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19271 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19272 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19273 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19274 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19275 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19276 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19277 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19278 .patch = patch_alc882 },
cb308f97 19279 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19280 .patch = patch_alc882 },
df694daa 19281 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19282 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19283 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19284 .patch = patch_alc882 },
274693f3 19285 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19286 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19287 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19288 {} /* terminator */
19289};
1289e9e8
TI
19290
19291MODULE_ALIAS("snd-hda-codec-id:10ec*");
19292
19293MODULE_LICENSE("GPL");
19294MODULE_DESCRIPTION("Realtek HD-audio codec");
19295
19296static struct hda_codec_preset_list realtek_list = {
19297 .preset = snd_hda_preset_realtek,
19298 .owner = THIS_MODULE,
19299};
19300
19301static int __init patch_realtek_init(void)
19302{
19303 return snd_hda_add_codec_preset(&realtek_list);
19304}
19305
19306static void __exit patch_realtek_exit(void)
19307{
19308 snd_hda_delete_codec_preset(&realtek_list);
19309}
19310
19311module_init(patch_realtek_init)
19312module_exit(patch_realtek_exit)