]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
Merge branch 'fix/hda' into topic/hda
[thirdparty/kernel/stable.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
680cd536 33#include "hda_beep.h"
1da177e4 34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
df99cd33 63 ALC880_MEDION_RIM,
e9edcee0
TI
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
df694daa 67 ALC880_AUTO,
16ded525
TI
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
3f878308 75 ALC260_HP_DC7600,
df694daa
KY
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
0bfc90e9 78 ALC260_ACER,
bc9f98a9
KY
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
cc959489 81 ALC260_FAVORIT100,
7cf51e48
JW
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
df694daa 85 ALC260_AUTO,
16ded525 86 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
87};
88
df694daa
KY
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
ccc656ce
KY
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
834be88d 94 ALC262_FUJITSU,
9c7f852e 95 ALC262_HP_BPC,
cd7509a4
KY
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
66d2a9d6 98 ALC262_HP_TC_T5735,
8c427226 99 ALC262_HP_RP5700,
304dcaac 100 ALC262_BENQ_ED8,
272a527c 101 ALC262_SONY_ASSAMD,
83c34218 102 ALC262_BENQ_T31,
f651b50b 103 ALC262_ULTRA,
0e31daf7 104 ALC262_LENOVO_3000,
e8f9ae2a 105 ALC262_NEC,
4e555fe5 106 ALC262_TOSHIBA_S06,
9f99a638 107 ALC262_TOSHIBA_RX1,
ba340e82 108 ALC262_TYAN,
df694daa
KY
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
a361d84b
KY
113/* ALC268 models */
114enum {
eb5a6621 115 ALC267_QUANTA_IL1,
a361d84b 116 ALC268_3ST,
d1a991a6 117 ALC268_TOSHIBA,
d273809e 118 ALC268_ACER,
c238b4f4 119 ALC268_ACER_DMIC,
8ef355da 120 ALC268_ACER_ASPIRE_ONE,
3866f0b0 121 ALC268_DELL,
f12462c5 122 ALC268_ZEPTO,
86c53bd2
JW
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
a361d84b
KY
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
f6a92248
KY
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
60db6b53 133 ALC269_QUANTA_FL1,
f53281e6
KY
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
26f5df26 136 ALC269_FUJITSU,
64154835 137 ALC269_LIFEBOOK,
f6a92248
KY
138 ALC269_AUTO,
139 ALC269_MODEL_LAST /* last tag */
140};
141
df694daa
KY
142/* ALC861 models */
143enum {
144 ALC861_3ST,
9c7f852e 145 ALC660_3ST,
df694daa
KY
146 ALC861_3ST_DIG,
147 ALC861_6ST_DIG,
22309c3e 148 ALC861_UNIWILL_M31,
a53d1aec 149 ALC861_TOSHIBA,
7cdbff94 150 ALC861_ASUS,
56bb0cab 151 ALC861_ASUS_LAPTOP,
df694daa
KY
152 ALC861_AUTO,
153 ALC861_MODEL_LAST,
154};
155
f32610ed
JS
156/* ALC861-VD models */
157enum {
158 ALC660VD_3ST,
6963f84c 159 ALC660VD_3ST_DIG,
13c94744 160 ALC660VD_ASUS_V1S,
f32610ed
JS
161 ALC861VD_3ST,
162 ALC861VD_3ST_DIG,
163 ALC861VD_6ST_DIG,
bdd148a3 164 ALC861VD_LENOVO,
272a527c 165 ALC861VD_DALLAS,
d1a991a6 166 ALC861VD_HP,
f32610ed
JS
167 ALC861VD_AUTO,
168 ALC861VD_MODEL_LAST,
169};
170
bc9f98a9
KY
171/* ALC662 models */
172enum {
173 ALC662_3ST_2ch_DIG,
174 ALC662_3ST_6ch_DIG,
175 ALC662_3ST_6ch,
176 ALC662_5ST_DIG,
177 ALC662_LENOVO_101E,
291702f0 178 ALC662_ASUS_EEEPC_P701,
8c427226 179 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
180 ALC663_ASUS_M51VA,
181 ALC663_ASUS_G71V,
182 ALC663_ASUS_H13,
183 ALC663_ASUS_G50V,
f1d4e28b
KY
184 ALC662_ECS,
185 ALC663_ASUS_MODE1,
186 ALC662_ASUS_MODE2,
187 ALC663_ASUS_MODE3,
188 ALC663_ASUS_MODE4,
189 ALC663_ASUS_MODE5,
190 ALC663_ASUS_MODE6,
622e84cd
KY
191 ALC272_DELL,
192 ALC272_DELL_ZM1,
bc9f98a9
KY
193 ALC662_AUTO,
194 ALC662_MODEL_LAST,
195};
196
df694daa
KY
197/* ALC882 models */
198enum {
199 ALC882_3ST_DIG,
200 ALC882_6ST_DIG,
4b146cb0 201 ALC882_ARIMA,
bdd148a3 202 ALC882_W2JC,
272a527c
KY
203 ALC882_TARGA,
204 ALC882_ASUS_A7J,
914759b7 205 ALC882_ASUS_A7M,
9102cd1c 206 ALC885_MACPRO,
87350ad0 207 ALC885_MBP3,
41d5545d 208 ALC885_MB5,
c54728d8 209 ALC885_IMAC24,
272a527c 210 ALC882_AUTO,
df694daa
KY
211 ALC882_MODEL_LAST,
212};
213
9c7f852e
TI
214/* ALC883 models */
215enum {
216 ALC883_3ST_2ch_DIG,
217 ALC883_3ST_6ch_DIG,
218 ALC883_3ST_6ch,
219 ALC883_6ST_DIG,
ccc656ce
KY
220 ALC883_TARGA_DIG,
221 ALC883_TARGA_2ch_DIG,
bab282b9 222 ALC883_ACER,
2880a867 223 ALC883_ACER_ASPIRE,
5b2d1eca 224 ALC888_ACER_ASPIRE_4930G,
c07584c8 225 ALC883_MEDION,
ea1fb29a 226 ALC883_MEDION_MD2,
b373bdeb 227 ALC883_LAPTOP_EAPD,
bc9f98a9 228 ALC883_LENOVO_101E_2ch,
272a527c 229 ALC883_LENOVO_NB0763,
189609ae 230 ALC888_LENOVO_MS7195_DIG,
e2757d5e 231 ALC888_LENOVO_SKY,
ea1fb29a 232 ALC883_HAIER_W66,
4723c022 233 ALC888_3ST_HP,
5795b9e6 234 ALC888_6ST_DELL,
a8848bd6 235 ALC883_MITAC,
0c4cc443 236 ALC883_CLEVO_M720,
fb97dc67 237 ALC883_FUJITSU_PI2515,
ef8ef5fb 238 ALC888_FUJITSU_XA3530,
17bba1b7 239 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
240 ALC888_ASUS_M90V,
241 ALC888_ASUS_EEE1601,
3ab90935 242 ALC1200_ASUS_P5Q,
9c7f852e
TI
243 ALC883_AUTO,
244 ALC883_MODEL_LAST,
245};
246
61b9b9b1
HRK
247/* styles of capture selection */
248enum {
249 CAPT_MUX = 0, /* only mux based */
250 CAPT_MIX, /* only mixer based */
251 CAPT_1MUX_MIX, /* first mux and other mixers */
252};
253
df694daa
KY
254/* for GPIO Poll */
255#define GPIO_MASK 0x03
256
4a79ba34
TI
257/* extra amp-initialization sequence types */
258enum {
259 ALC_INIT_NONE,
260 ALC_INIT_DEFAULT,
261 ALC_INIT_GPIO1,
262 ALC_INIT_GPIO2,
263 ALC_INIT_GPIO3,
264};
265
1da177e4
LT
266struct alc_spec {
267 /* codec parameterization */
df694daa 268 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 269 unsigned int num_mixers;
f9e336f6 270 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 271 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 272
df694daa 273 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
274 * don't forget NULL
275 * termination!
e9edcee0
TI
276 */
277 unsigned int num_init_verbs;
1da177e4 278
16ded525 279 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
280 struct hda_pcm_stream *stream_analog_playback;
281 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
282 struct hda_pcm_stream *stream_analog_alt_playback;
283 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 284
f12ab1e0 285 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
286 struct hda_pcm_stream *stream_digital_playback;
287 struct hda_pcm_stream *stream_digital_capture;
288
289 /* playback */
16ded525
TI
290 struct hda_multi_out multiout; /* playback set-up
291 * max_channels, dacs must be set
292 * dig_out_nid and hp_nid are optional
293 */
6330079f 294 hda_nid_t alt_dac_nid;
6a05ac4a 295 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 296 int dig_out_type;
1da177e4
LT
297
298 /* capture */
299 unsigned int num_adc_nids;
300 hda_nid_t *adc_nids;
e1406348 301 hda_nid_t *capsrc_nids;
16ded525 302 hda_nid_t dig_in_nid; /* digital-in NID; optional */
61b9b9b1 303 int capture_style; /* capture style (CAPT_*) */
1da177e4
LT
304
305 /* capture source */
a1e8d2da 306 unsigned int num_mux_defs;
1da177e4
LT
307 const struct hda_input_mux *input_mux;
308 unsigned int cur_mux[3];
309
310 /* channel model */
d2a6d7dc 311 const struct hda_channel_mode *channel_mode;
1da177e4 312 int num_channel_mode;
4e195a7b 313 int need_dac_fix;
1da177e4
LT
314
315 /* PCM information */
4c5186ed 316 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 317
e9edcee0
TI
318 /* dynamic controls, init_verbs and input_mux */
319 struct auto_pin_cfg autocfg;
603c4019 320 struct snd_array kctls;
61b9b9b1 321 struct hda_input_mux private_imux[3];
41923e44 322 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 323
ae6b813a
TI
324 /* hooks */
325 void (*init_hook)(struct hda_codec *codec);
326 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
327
834be88d
TI
328 /* for pin sensing */
329 unsigned int sense_updated: 1;
330 unsigned int jack_present: 1;
bec15c3a 331 unsigned int master_sw: 1;
cb53c626 332
e64f14f4
TI
333 /* other flags */
334 unsigned int no_analog :1; /* digital I/O only */
4a79ba34 335 int init_amp;
e64f14f4 336
2134ea4f
TI
337 /* for virtual master */
338 hda_nid_t vmaster_nid;
cb53c626
TI
339#ifdef CONFIG_SND_HDA_POWER_SAVE
340 struct hda_loopback_check loopback;
341#endif
2c3bf9ab
TI
342
343 /* for PLL fix */
344 hda_nid_t pll_nid;
345 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
346};
347
348/*
349 * configuration template - to be copied to the spec instance
350 */
351struct alc_config_preset {
9c7f852e
TI
352 struct snd_kcontrol_new *mixers[5]; /* should be identical size
353 * with spec
354 */
f9e336f6 355 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
356 const struct hda_verb *init_verbs[5];
357 unsigned int num_dacs;
358 hda_nid_t *dac_nids;
359 hda_nid_t dig_out_nid; /* optional */
360 hda_nid_t hp_nid; /* optional */
b25c9da1 361 hda_nid_t *slave_dig_outs;
df694daa
KY
362 unsigned int num_adc_nids;
363 hda_nid_t *adc_nids;
e1406348 364 hda_nid_t *capsrc_nids;
df694daa
KY
365 hda_nid_t dig_in_nid;
366 unsigned int num_channel_mode;
367 const struct hda_channel_mode *channel_mode;
4e195a7b 368 int need_dac_fix;
a1e8d2da 369 unsigned int num_mux_defs;
df694daa 370 const struct hda_input_mux *input_mux;
ae6b813a
TI
371 void (*unsol_event)(struct hda_codec *, unsigned int);
372 void (*init_hook)(struct hda_codec *);
cb53c626
TI
373#ifdef CONFIG_SND_HDA_POWER_SAVE
374 struct hda_amp_list *loopbacks;
375#endif
1da177e4
LT
376};
377
1da177e4
LT
378
379/*
380 * input MUX handling
381 */
9c7f852e
TI
382static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
384{
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
387 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
388 if (mux_idx >= spec->num_mux_defs)
389 mux_idx = 0;
390 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
391}
392
9c7f852e
TI
393static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
395{
396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct alc_spec *spec = codec->spec;
398 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
399
400 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
401 return 0;
402}
403
9c7f852e
TI
404static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
406{
407 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
408 struct alc_spec *spec = codec->spec;
cd896c33 409 const struct hda_input_mux *imux;
1da177e4 410 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 411 unsigned int mux_idx;
e1406348
TI
412 hda_nid_t nid = spec->capsrc_nids ?
413 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4 414
cd896c33
TI
415 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
416 imux = &spec->input_mux[mux_idx];
417
61b9b9b1
HRK
418 if (spec->capture_style &&
419 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
54cbc9ab
TI
420 /* Matrix-mixer style (e.g. ALC882) */
421 unsigned int *cur_val = &spec->cur_mux[adc_idx];
422 unsigned int i, idx;
423
424 idx = ucontrol->value.enumerated.item[0];
425 if (idx >= imux->num_items)
426 idx = imux->num_items - 1;
427 if (*cur_val == idx)
428 return 0;
429 for (i = 0; i < imux->num_items; i++) {
430 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
431 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
432 imux->items[i].index,
433 HDA_AMP_MUTE, v);
434 }
435 *cur_val = idx;
436 return 1;
437 } else {
438 /* MUX style (e.g. ALC880) */
cd896c33 439 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
440 &spec->cur_mux[adc_idx]);
441 }
442}
e9edcee0 443
1da177e4
LT
444/*
445 * channel mode setting
446 */
9c7f852e
TI
447static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
449{
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
452 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
453 spec->num_channel_mode);
1da177e4
LT
454}
455
9c7f852e
TI
456static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
458{
459 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
460 struct alc_spec *spec = codec->spec;
d2a6d7dc 461 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
462 spec->num_channel_mode,
463 spec->multiout.max_channels);
1da177e4
LT
464}
465
9c7f852e
TI
466static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
468{
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 struct alc_spec *spec = codec->spec;
4e195a7b
TI
471 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
472 spec->num_channel_mode,
473 &spec->multiout.max_channels);
bd2033f2 474 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
475 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
476 return err;
1da177e4
LT
477}
478
a9430dd8 479/*
4c5186ed 480 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 481 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
482 * being part of a format specifier. Maximum allowed length of a value is
483 * 63 characters plus NULL terminator.
7cf51e48
JW
484 *
485 * Note: some retasking pin complexes seem to ignore requests for input
486 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
487 * are requested. Therefore order this list so that this behaviour will not
488 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
489 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
490 * March 2006.
4c5186ed
JW
491 */
492static char *alc_pin_mode_names[] = {
7cf51e48
JW
493 "Mic 50pc bias", "Mic 80pc bias",
494 "Line in", "Line out", "Headphone out",
4c5186ed
JW
495};
496static unsigned char alc_pin_mode_values[] = {
7cf51e48 497 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
498};
499/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
500 * in the pin being assumed to be exclusively an input or an output pin. In
501 * addition, "input" pins may or may not process the mic bias option
502 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
503 * accept requests for bias as of chip versions up to March 2006) and/or
504 * wiring in the computer.
a9430dd8 505 */
a1e8d2da
JW
506#define ALC_PIN_DIR_IN 0x00
507#define ALC_PIN_DIR_OUT 0x01
508#define ALC_PIN_DIR_INOUT 0x02
509#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
510#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 511
ea1fb29a 512/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
513 * For each direction the minimum and maximum values are given.
514 */
a1e8d2da 515static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
516 { 0, 2 }, /* ALC_PIN_DIR_IN */
517 { 3, 4 }, /* ALC_PIN_DIR_OUT */
518 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
519 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
520 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
521};
522#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
523#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
524#define alc_pin_mode_n_items(_dir) \
525 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
526
9c7f852e
TI
527static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
528 struct snd_ctl_elem_info *uinfo)
a9430dd8 529{
4c5186ed
JW
530 unsigned int item_num = uinfo->value.enumerated.item;
531 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
532
533 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 534 uinfo->count = 1;
4c5186ed
JW
535 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
536
537 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
538 item_num = alc_pin_mode_min(dir);
539 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
540 return 0;
541}
542
9c7f852e
TI
543static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
a9430dd8 545{
4c5186ed 546 unsigned int i;
a9430dd8
JW
547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 549 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 550 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
551 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
552 AC_VERB_GET_PIN_WIDGET_CONTROL,
553 0x00);
a9430dd8 554
4c5186ed
JW
555 /* Find enumerated value for current pinctl setting */
556 i = alc_pin_mode_min(dir);
9c7f852e 557 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 558 i++;
9c7f852e 559 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
560 return 0;
561}
562
9c7f852e
TI
563static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
a9430dd8 565{
4c5186ed 566 signed int change;
a9430dd8
JW
567 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
568 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
569 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
570 long val = *ucontrol->value.integer.value;
9c7f852e
TI
571 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
572 AC_VERB_GET_PIN_WIDGET_CONTROL,
573 0x00);
a9430dd8 574
f12ab1e0 575 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
576 val = alc_pin_mode_min(dir);
577
578 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
579 if (change) {
580 /* Set pin mode to that requested */
82beb8fd
TI
581 snd_hda_codec_write_cache(codec, nid, 0,
582 AC_VERB_SET_PIN_WIDGET_CONTROL,
583 alc_pin_mode_values[val]);
cdcd9268 584
ea1fb29a 585 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
586 * for the requested pin mode. Enum values of 2 or less are
587 * input modes.
588 *
589 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
590 * reduces noise slightly (particularly on input) so we'll
591 * do it. However, having both input and output buffers
592 * enabled simultaneously doesn't seem to be problematic if
593 * this turns out to be necessary in the future.
cdcd9268
JW
594 */
595 if (val <= 2) {
47fd830a
TI
596 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
597 HDA_AMP_MUTE, HDA_AMP_MUTE);
598 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
599 HDA_AMP_MUTE, 0);
cdcd9268 600 } else {
47fd830a
TI
601 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
602 HDA_AMP_MUTE, HDA_AMP_MUTE);
603 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
604 HDA_AMP_MUTE, 0);
cdcd9268
JW
605 }
606 }
a9430dd8
JW
607 return change;
608}
609
4c5186ed 610#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 611 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
612 .info = alc_pin_mode_info, \
613 .get = alc_pin_mode_get, \
614 .put = alc_pin_mode_put, \
615 .private_value = nid | (dir<<16) }
df694daa 616
5c8f858d
JW
617/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
618 * together using a mask with more than one bit set. This control is
619 * currently used only by the ALC260 test model. At this stage they are not
620 * needed for any "production" models.
621 */
622#ifdef CONFIG_SND_DEBUG
a5ce8890 623#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 624
9c7f852e
TI
625static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
626 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
627{
628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
629 hda_nid_t nid = kcontrol->private_value & 0xffff;
630 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
631 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
632 unsigned int val = snd_hda_codec_read(codec, nid, 0,
633 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
634
635 *valp = (val & mask) != 0;
636 return 0;
637}
9c7f852e
TI
638static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
639 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
640{
641 signed int change;
642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
643 hda_nid_t nid = kcontrol->private_value & 0xffff;
644 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
645 long val = *ucontrol->value.integer.value;
9c7f852e
TI
646 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
647 AC_VERB_GET_GPIO_DATA,
648 0x00);
5c8f858d
JW
649
650 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
651 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
652 if (val == 0)
5c8f858d
JW
653 gpio_data &= ~mask;
654 else
655 gpio_data |= mask;
82beb8fd
TI
656 snd_hda_codec_write_cache(codec, nid, 0,
657 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
658
659 return change;
660}
661#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
662 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
663 .info = alc_gpio_data_info, \
664 .get = alc_gpio_data_get, \
665 .put = alc_gpio_data_put, \
666 .private_value = nid | (mask<<16) }
667#endif /* CONFIG_SND_DEBUG */
668
92621f13
JW
669/* A switch control to allow the enabling of the digital IO pins on the
670 * ALC260. This is incredibly simplistic; the intention of this control is
671 * to provide something in the test model allowing digital outputs to be
672 * identified if present. If models are found which can utilise these
673 * outputs a more complete mixer control can be devised for those models if
674 * necessary.
675 */
676#ifdef CONFIG_SND_DEBUG
a5ce8890 677#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 678
9c7f852e
TI
679static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
681{
682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
683 hda_nid_t nid = kcontrol->private_value & 0xffff;
684 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
685 long *valp = ucontrol->value.integer.value;
9c7f852e 686 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 687 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
688
689 *valp = (val & mask) != 0;
690 return 0;
691}
9c7f852e
TI
692static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
694{
695 signed int change;
696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
697 hda_nid_t nid = kcontrol->private_value & 0xffff;
698 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
699 long val = *ucontrol->value.integer.value;
9c7f852e 700 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 701 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 702 0x00);
92621f13
JW
703
704 /* Set/unset the masked control bit(s) as needed */
9c7f852e 705 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
706 if (val==0)
707 ctrl_data &= ~mask;
708 else
709 ctrl_data |= mask;
82beb8fd
TI
710 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
711 ctrl_data);
92621f13
JW
712
713 return change;
714}
715#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
716 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
717 .info = alc_spdif_ctrl_info, \
718 .get = alc_spdif_ctrl_get, \
719 .put = alc_spdif_ctrl_put, \
720 .private_value = nid | (mask<<16) }
721#endif /* CONFIG_SND_DEBUG */
722
f8225f6d
JW
723/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
724 * Again, this is only used in the ALC26x test models to help identify when
725 * the EAPD line must be asserted for features to work.
726 */
727#ifdef CONFIG_SND_DEBUG
728#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
729
730static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
731 struct snd_ctl_elem_value *ucontrol)
732{
733 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
734 hda_nid_t nid = kcontrol->private_value & 0xffff;
735 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
736 long *valp = ucontrol->value.integer.value;
737 unsigned int val = snd_hda_codec_read(codec, nid, 0,
738 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
739
740 *valp = (val & mask) != 0;
741 return 0;
742}
743
744static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
745 struct snd_ctl_elem_value *ucontrol)
746{
747 int change;
748 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
749 hda_nid_t nid = kcontrol->private_value & 0xffff;
750 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
751 long val = *ucontrol->value.integer.value;
752 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
753 AC_VERB_GET_EAPD_BTLENABLE,
754 0x00);
755
756 /* Set/unset the masked control bit(s) as needed */
757 change = (!val ? 0 : mask) != (ctrl_data & mask);
758 if (!val)
759 ctrl_data &= ~mask;
760 else
761 ctrl_data |= mask;
762 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
763 ctrl_data);
764
765 return change;
766}
767
768#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
769 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
770 .info = alc_eapd_ctrl_info, \
771 .get = alc_eapd_ctrl_get, \
772 .put = alc_eapd_ctrl_put, \
773 .private_value = nid | (mask<<16) }
774#endif /* CONFIG_SND_DEBUG */
775
23f0c048
TI
776/*
777 * set up the input pin config (depending on the given auto-pin type)
778 */
779static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
780 int auto_pin_type)
781{
782 unsigned int val = PIN_IN;
783
784 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
785 unsigned int pincap;
1327a32b 786 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
787 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
788 if (pincap & AC_PINCAP_VREF_80)
789 val = PIN_VREF80;
790 }
791 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
792}
793
d88897ea
TI
794/*
795 */
796static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
797{
798 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
799 return;
800 spec->mixers[spec->num_mixers++] = mix;
801}
802
803static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
804{
805 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
806 return;
807 spec->init_verbs[spec->num_init_verbs++] = verb;
808}
809
daead538
TI
810#ifdef CONFIG_PROC_FS
811/*
812 * hook for proc
813 */
814static void print_realtek_coef(struct snd_info_buffer *buffer,
815 struct hda_codec *codec, hda_nid_t nid)
816{
817 int coeff;
818
819 if (nid != 0x20)
820 return;
821 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
822 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
823 coeff = snd_hda_codec_read(codec, nid, 0,
824 AC_VERB_GET_COEF_INDEX, 0);
825 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
826}
827#else
828#define print_realtek_coef NULL
829#endif
830
df694daa
KY
831/*
832 * set up from the preset table
833 */
9c7f852e
TI
834static void setup_preset(struct alc_spec *spec,
835 const struct alc_config_preset *preset)
df694daa
KY
836{
837 int i;
838
839 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 840 add_mixer(spec, preset->mixers[i]);
f9e336f6 841 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
842 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
843 i++)
d88897ea 844 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 845
df694daa
KY
846 spec->channel_mode = preset->channel_mode;
847 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 848 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
849
850 spec->multiout.max_channels = spec->channel_mode[0].channels;
851
852 spec->multiout.num_dacs = preset->num_dacs;
853 spec->multiout.dac_nids = preset->dac_nids;
854 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 855 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 856 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 857
a1e8d2da 858 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 859 if (!spec->num_mux_defs)
a1e8d2da 860 spec->num_mux_defs = 1;
df694daa
KY
861 spec->input_mux = preset->input_mux;
862
863 spec->num_adc_nids = preset->num_adc_nids;
864 spec->adc_nids = preset->adc_nids;
e1406348 865 spec->capsrc_nids = preset->capsrc_nids;
df694daa 866 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
867
868 spec->unsol_event = preset->unsol_event;
869 spec->init_hook = preset->init_hook;
cb53c626
TI
870#ifdef CONFIG_SND_HDA_POWER_SAVE
871 spec->loopback.amplist = preset->loopbacks;
872#endif
df694daa
KY
873}
874
bc9f98a9
KY
875/* Enable GPIO mask and set output */
876static struct hda_verb alc_gpio1_init_verbs[] = {
877 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
878 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
879 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
880 { }
881};
882
883static struct hda_verb alc_gpio2_init_verbs[] = {
884 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
885 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
886 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
887 { }
888};
889
bdd148a3
KY
890static struct hda_verb alc_gpio3_init_verbs[] = {
891 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
892 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
893 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
894 { }
895};
896
2c3bf9ab
TI
897/*
898 * Fix hardware PLL issue
899 * On some codecs, the analog PLL gating control must be off while
900 * the default value is 1.
901 */
902static void alc_fix_pll(struct hda_codec *codec)
903{
904 struct alc_spec *spec = codec->spec;
905 unsigned int val;
906
907 if (!spec->pll_nid)
908 return;
909 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
910 spec->pll_coef_idx);
911 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
912 AC_VERB_GET_PROC_COEF, 0);
913 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
914 spec->pll_coef_idx);
915 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
916 val & ~(1 << spec->pll_coef_bit));
917}
918
919static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
920 unsigned int coef_idx, unsigned int coef_bit)
921{
922 struct alc_spec *spec = codec->spec;
923 spec->pll_nid = nid;
924 spec->pll_coef_idx = coef_idx;
925 spec->pll_coef_bit = coef_bit;
926 alc_fix_pll(codec);
927}
928
a9fd4f3f 929static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
930{
931 struct alc_spec *spec = codec->spec;
c9b58006 932 unsigned int present;
a9fd4f3f
TI
933 unsigned int nid = spec->autocfg.hp_pins[0];
934 int i;
c9b58006
KY
935
936 /* need to execute and sync at first */
a9fd4f3f
TI
937 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
938 present = snd_hda_codec_read(codec, nid, 0,
c9b58006 939 AC_VERB_GET_PIN_SENSE, 0);
a9fd4f3f
TI
940 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
941 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
942 nid = spec->autocfg.speaker_pins[i];
943 if (!nid)
944 break;
945 snd_hda_codec_write(codec, nid, 0,
946 AC_VERB_SET_PIN_WIDGET_CONTROL,
947 spec->jack_present ? 0 : PIN_OUT);
948 }
c9b58006
KY
949}
950
4605b718 951#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
952static void alc_mic_automute(struct hda_codec *codec)
953{
954 struct alc_spec *spec = codec->spec;
955 unsigned int present;
956 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
957 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
958 unsigned int mix_nid = spec->capsrc_nids[0];
959 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
960
961 capsrc_idx_mic = mic_nid - 0x18;
962 capsrc_idx_fmic = fmic_nid - 0x18;
963 present = snd_hda_codec_read(codec, mic_nid, 0,
964 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
965 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
966 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
967 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
968 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
969 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
970 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
971}
4605b718 972#else
45bdd1c1 973#define alc_mic_automute(codec) do {} while(0) /* NOP */
4605b718 974#endif /* disabled */
7fb0d78f 975
c9b58006
KY
976/* unsolicited event for HP jack sensing */
977static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
978{
979 if (codec->vendor_id == 0x10ec0880)
980 res >>= 28;
981 else
982 res >>= 26;
a9fd4f3f
TI
983 switch (res) {
984 case ALC880_HP_EVENT:
985 alc_automute_pin(codec);
986 break;
987 case ALC880_MIC_EVENT:
7fb0d78f 988 alc_mic_automute(codec);
a9fd4f3f
TI
989 break;
990 }
7fb0d78f
KY
991}
992
993static void alc_inithook(struct hda_codec *codec)
994{
a9fd4f3f 995 alc_automute_pin(codec);
7fb0d78f 996 alc_mic_automute(codec);
c9b58006
KY
997}
998
f9423e7a
KY
999/* additional initialization for ALC888 variants */
1000static void alc888_coef_init(struct hda_codec *codec)
1001{
1002 unsigned int tmp;
1003
1004 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1005 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1006 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1007 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1008 /* alc888S-VC */
1009 snd_hda_codec_read(codec, 0x20, 0,
1010 AC_VERB_SET_PROC_COEF, 0x830);
1011 else
1012 /* alc888-VB */
1013 snd_hda_codec_read(codec, 0x20, 0,
1014 AC_VERB_SET_PROC_COEF, 0x3030);
1015}
1016
4a79ba34 1017static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1018{
4a79ba34 1019 unsigned int tmp;
bc9f98a9 1020
4a79ba34
TI
1021 switch (type) {
1022 case ALC_INIT_GPIO1:
bc9f98a9
KY
1023 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1024 break;
4a79ba34 1025 case ALC_INIT_GPIO2:
bc9f98a9
KY
1026 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1027 break;
4a79ba34 1028 case ALC_INIT_GPIO3:
bdd148a3
KY
1029 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1030 break;
4a79ba34 1031 case ALC_INIT_DEFAULT:
bdd148a3 1032 switch (codec->vendor_id) {
c9b58006
KY
1033 case 0x10ec0260:
1034 snd_hda_codec_write(codec, 0x0f, 0,
1035 AC_VERB_SET_EAPD_BTLENABLE, 2);
1036 snd_hda_codec_write(codec, 0x10, 0,
1037 AC_VERB_SET_EAPD_BTLENABLE, 2);
1038 break;
1039 case 0x10ec0262:
bdd148a3
KY
1040 case 0x10ec0267:
1041 case 0x10ec0268:
c9b58006 1042 case 0x10ec0269:
c6e8f2da 1043 case 0x10ec0272:
f9423e7a
KY
1044 case 0x10ec0660:
1045 case 0x10ec0662:
1046 case 0x10ec0663:
c9b58006 1047 case 0x10ec0862:
20a3a05d 1048 case 0x10ec0889:
bdd148a3
KY
1049 snd_hda_codec_write(codec, 0x14, 0,
1050 AC_VERB_SET_EAPD_BTLENABLE, 2);
1051 snd_hda_codec_write(codec, 0x15, 0,
1052 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 1053 break;
bdd148a3 1054 }
c9b58006
KY
1055 switch (codec->vendor_id) {
1056 case 0x10ec0260:
1057 snd_hda_codec_write(codec, 0x1a, 0,
1058 AC_VERB_SET_COEF_INDEX, 7);
1059 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1060 AC_VERB_GET_PROC_COEF, 0);
1061 snd_hda_codec_write(codec, 0x1a, 0,
1062 AC_VERB_SET_COEF_INDEX, 7);
1063 snd_hda_codec_write(codec, 0x1a, 0,
1064 AC_VERB_SET_PROC_COEF,
1065 tmp | 0x2010);
1066 break;
1067 case 0x10ec0262:
1068 case 0x10ec0880:
1069 case 0x10ec0882:
1070 case 0x10ec0883:
1071 case 0x10ec0885:
4a5a4c56 1072 case 0x10ec0887:
20a3a05d 1073 case 0x10ec0889:
c9b58006
KY
1074 snd_hda_codec_write(codec, 0x20, 0,
1075 AC_VERB_SET_COEF_INDEX, 7);
1076 tmp = snd_hda_codec_read(codec, 0x20, 0,
1077 AC_VERB_GET_PROC_COEF, 0);
1078 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1079 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1080 snd_hda_codec_write(codec, 0x20, 0,
1081 AC_VERB_SET_PROC_COEF,
1082 tmp | 0x2010);
1083 break;
f9423e7a 1084 case 0x10ec0888:
4a79ba34 1085 alc888_coef_init(codec);
f9423e7a 1086 break;
c9b58006
KY
1087 case 0x10ec0267:
1088 case 0x10ec0268:
1089 snd_hda_codec_write(codec, 0x20, 0,
1090 AC_VERB_SET_COEF_INDEX, 7);
1091 tmp = snd_hda_codec_read(codec, 0x20, 0,
1092 AC_VERB_GET_PROC_COEF, 0);
1093 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1094 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1095 snd_hda_codec_write(codec, 0x20, 0,
1096 AC_VERB_SET_PROC_COEF,
1097 tmp | 0x3000);
1098 break;
bc9f98a9 1099 }
4a79ba34
TI
1100 break;
1101 }
1102}
1103
1104static void alc_init_auto_hp(struct hda_codec *codec)
1105{
1106 struct alc_spec *spec = codec->spec;
1107
1108 if (!spec->autocfg.hp_pins[0])
1109 return;
1110
1111 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1112 if (spec->autocfg.line_out_pins[0] &&
1113 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1114 spec->autocfg.speaker_pins[0] =
1115 spec->autocfg.line_out_pins[0];
1116 else
1117 return;
1118 }
1119
2a2ed0df
TI
1120 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1121 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1122 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1123 AC_VERB_SET_UNSOLICITED_ENABLE,
1124 AC_USRSP_EN | ALC880_HP_EVENT);
1125 spec->unsol_event = alc_sku_unsol_event;
1126}
1127
1128/* check subsystem ID and set up device-specific initialization;
1129 * return 1 if initialized, 0 if invalid SSID
1130 */
1131/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1132 * 31 ~ 16 : Manufacture ID
1133 * 15 ~ 8 : SKU ID
1134 * 7 ~ 0 : Assembly ID
1135 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1136 */
1137static int alc_subsystem_id(struct hda_codec *codec,
1138 hda_nid_t porta, hda_nid_t porte,
1139 hda_nid_t portd)
1140{
1141 unsigned int ass, tmp, i;
1142 unsigned nid;
1143 struct alc_spec *spec = codec->spec;
1144
1145 ass = codec->subsystem_id & 0xffff;
1146 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1147 goto do_sku;
1148
1149 /* invalid SSID, check the special NID pin defcfg instead */
1150 /*
1151 * 31~30 : port conetcivity
1152 * 29~21 : reserve
1153 * 20 : PCBEEP input
1154 * 19~16 : Check sum (15:1)
1155 * 15~1 : Custom
1156 * 0 : override
1157 */
1158 nid = 0x1d;
1159 if (codec->vendor_id == 0x10ec0260)
1160 nid = 0x17;
1161 ass = snd_hda_codec_get_pincfg(codec, nid);
1162 snd_printd("realtek: No valid SSID, "
1163 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1164 ass, nid);
4a79ba34
TI
1165 if (!(ass & 1) && !(ass & 0x100000))
1166 return 0;
1167 if ((ass >> 30) != 1) /* no physical connection */
1168 return 0;
1169
1170 /* check sum */
1171 tmp = 0;
1172 for (i = 1; i < 16; i++) {
1173 if ((ass >> i) & 1)
1174 tmp++;
1175 }
1176 if (((ass >> 16) & 0xf) != tmp)
1177 return 0;
1178do_sku:
1179 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1180 ass & 0xffff, codec->vendor_id);
1181 /*
1182 * 0 : override
1183 * 1 : Swap Jack
1184 * 2 : 0 --> Desktop, 1 --> Laptop
1185 * 3~5 : External Amplifier control
1186 * 7~6 : Reserved
1187 */
1188 tmp = (ass & 0x38) >> 3; /* external Amp control */
1189 switch (tmp) {
1190 case 1:
1191 spec->init_amp = ALC_INIT_GPIO1;
1192 break;
1193 case 3:
1194 spec->init_amp = ALC_INIT_GPIO2;
1195 break;
1196 case 7:
1197 spec->init_amp = ALC_INIT_GPIO3;
1198 break;
1199 case 5:
1200 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1201 break;
1202 }
ea1fb29a 1203
8c427226 1204 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1205 * when the external headphone out jack is plugged"
1206 */
8c427226 1207 if (!(ass & 0x8000))
4a79ba34 1208 return 1;
c9b58006
KY
1209 /*
1210 * 10~8 : Jack location
1211 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1212 * 14~13: Resvered
1213 * 15 : 1 --> enable the function "Mute internal speaker
1214 * when the external headphone out jack is plugged"
1215 */
c9b58006
KY
1216 if (!spec->autocfg.hp_pins[0]) {
1217 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1218 if (tmp == 0)
1219 spec->autocfg.hp_pins[0] = porta;
1220 else if (tmp == 1)
1221 spec->autocfg.hp_pins[0] = porte;
1222 else if (tmp == 2)
1223 spec->autocfg.hp_pins[0] = portd;
1224 else
4a79ba34 1225 return 1;
c9b58006
KY
1226 }
1227
4a79ba34
TI
1228 alc_init_auto_hp(codec);
1229 return 1;
1230}
ea1fb29a 1231
4a79ba34
TI
1232static void alc_ssid_check(struct hda_codec *codec,
1233 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1234{
1235 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1236 struct alc_spec *spec = codec->spec;
1237 snd_printd("realtek: "
1238 "Enable default setup for auto mode as fallback\n");
1239 spec->init_amp = ALC_INIT_DEFAULT;
1240 alc_init_auto_hp(codec);
1241 }
bc9f98a9
KY
1242}
1243
f95474ec
TI
1244/*
1245 * Fix-up pin default configurations
1246 */
1247
1248struct alc_pincfg {
1249 hda_nid_t nid;
1250 u32 val;
1251};
1252
1253static void alc_fix_pincfg(struct hda_codec *codec,
1254 const struct snd_pci_quirk *quirk,
1255 const struct alc_pincfg **pinfix)
1256{
1257 const struct alc_pincfg *cfg;
1258
1259 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1260 if (!quirk)
1261 return;
1262
1263 cfg = pinfix[quirk->value];
0e8a21b5
TI
1264 for (; cfg->nid; cfg++)
1265 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
f95474ec
TI
1266}
1267
ef8ef5fb
VP
1268/*
1269 * ALC888
1270 */
1271
1272/*
1273 * 2ch mode
1274 */
1275static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1276/* Mic-in jack as mic in */
1277 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1278 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1279/* Line-in jack as Line in */
1280 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1281 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1282/* Line-Out as Front */
1283 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1284 { } /* end */
1285};
1286
1287/*
1288 * 4ch mode
1289 */
1290static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1291/* Mic-in jack as mic in */
1292 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1293 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1294/* Line-in jack as Surround */
1295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1296 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1297/* Line-Out as Front */
1298 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1299 { } /* end */
1300};
1301
1302/*
1303 * 6ch mode
1304 */
1305static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1306/* Mic-in jack as CLFE */
1307 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1308 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1309/* Line-in jack as Surround */
1310 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1311 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1312/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1313 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1314 { } /* end */
1315};
1316
1317/*
1318 * 8ch mode
1319 */
1320static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1321/* Mic-in jack as CLFE */
1322 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1323 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1324/* Line-in jack as Surround */
1325 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1326 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1327/* Line-Out as Side */
1328 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1329 { } /* end */
1330};
1331
1332static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1333 { 2, alc888_4ST_ch2_intel_init },
1334 { 4, alc888_4ST_ch4_intel_init },
1335 { 6, alc888_4ST_ch6_intel_init },
1336 { 8, alc888_4ST_ch8_intel_init },
1337};
1338
1339/*
1340 * ALC888 Fujitsu Siemens Amillo xa3530
1341 */
1342
1343static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1344/* Front Mic: set to PIN_IN (empty by default) */
1345 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1346/* Connect Internal HP to Front */
1347 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1348 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1349 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1350/* Connect Bass HP to Front */
1351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1352 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1354/* Connect Line-Out side jack (SPDIF) to Side */
1355 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1356 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1357 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1358/* Connect Mic jack to CLFE */
1359 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1360 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1361 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1362/* Connect Line-in jack to Surround */
1363 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1364 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1365 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1366/* Connect HP out jack to Front */
1367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1370/* Enable unsolicited event for HP jack and Line-out jack */
1371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1372 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1373 {}
1374};
1375
a9fd4f3f 1376static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1377{
a9fd4f3f
TI
1378 struct alc_spec *spec = codec->spec;
1379 unsigned int val, mute;
1380 hda_nid_t nid;
1381 int i;
1382
1383 spec->jack_present = 0;
1384 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1385 nid = spec->autocfg.hp_pins[i];
1386 if (!nid)
1387 break;
1388 val = snd_hda_codec_read(codec, nid, 0,
1389 AC_VERB_GET_PIN_SENSE, 0);
1390 if (val & AC_PINSENSE_PRESENCE) {
1391 spec->jack_present = 1;
1392 break;
1393 }
1394 }
1395
1396 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1397 /* Toggle internal speakers muting */
a9fd4f3f
TI
1398 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1399 nid = spec->autocfg.speaker_pins[i];
1400 if (!nid)
1401 break;
1402 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1403 HDA_AMP_MUTE, mute);
1404 }
ef8ef5fb
VP
1405}
1406
a9fd4f3f
TI
1407static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1408 unsigned int res)
ef8ef5fb 1409{
a9fd4f3f
TI
1410 if (codec->vendor_id == 0x10ec0880)
1411 res >>= 28;
1412 else
1413 res >>= 26;
1414 if (res == ALC880_HP_EVENT)
1415 alc_automute_amp(codec);
ef8ef5fb
VP
1416}
1417
a9fd4f3f
TI
1418static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1419{
1420 struct alc_spec *spec = codec->spec;
1421
1422 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1423 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1424 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1425 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1426 alc_automute_amp(codec);
1427}
ef8ef5fb 1428
5b2d1eca
VP
1429/*
1430 * ALC888 Acer Aspire 4930G model
1431 */
1432
1433static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1434/* Front Mic: set to PIN_IN (empty by default) */
1435 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1436/* Unselect Front Mic by default in input mixer 3 */
1437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1438/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1440/* Connect Internal HP to front */
1441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1442 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1443 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1444/* Connect HP out to front */
1445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1447 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1448 { }
1449};
1450
ef8ef5fb 1451static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1452 /* Front mic only available on one ADC */
1453 {
1454 .num_items = 4,
1455 .items = {
1456 { "Mic", 0x0 },
1457 { "Line", 0x2 },
1458 { "CD", 0x4 },
1459 { "Front Mic", 0xb },
1460 },
1461 },
1462 {
1463 .num_items = 3,
1464 .items = {
1465 { "Mic", 0x0 },
1466 { "Line", 0x2 },
1467 { "CD", 0x4 },
1468 },
1469 }
1470};
1471
ef8ef5fb 1472static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1473 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1474 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1475 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1476 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1477 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1478 HDA_OUTPUT),
1479 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1480 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1481 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1482 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1483 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1484 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1485 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1486 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1487 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1489 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1490 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1491 { } /* end */
1492};
1493
a9fd4f3f 1494static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
5b2d1eca 1495{
a9fd4f3f 1496 struct alc_spec *spec = codec->spec;
5b2d1eca 1497
a9fd4f3f
TI
1498 spec->autocfg.hp_pins[0] = 0x15;
1499 spec->autocfg.speaker_pins[0] = 0x14;
1500 alc_automute_amp(codec);
5b2d1eca
VP
1501}
1502
1da177e4 1503/*
e9edcee0
TI
1504 * ALC880 3-stack model
1505 *
1506 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1507 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1508 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1509 */
1510
e9edcee0
TI
1511static hda_nid_t alc880_dac_nids[4] = {
1512 /* front, rear, clfe, rear_surr */
1513 0x02, 0x05, 0x04, 0x03
1514};
1515
1516static hda_nid_t alc880_adc_nids[3] = {
1517 /* ADC0-2 */
1518 0x07, 0x08, 0x09,
1519};
1520
1521/* The datasheet says the node 0x07 is connected from inputs,
1522 * but it shows zero connection in the real implementation on some devices.
df694daa 1523 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1524 */
e9edcee0
TI
1525static hda_nid_t alc880_adc_nids_alt[2] = {
1526 /* ADC1-2 */
1527 0x08, 0x09,
1528};
1529
1530#define ALC880_DIGOUT_NID 0x06
1531#define ALC880_DIGIN_NID 0x0a
1532
1533static struct hda_input_mux alc880_capture_source = {
1534 .num_items = 4,
1535 .items = {
1536 { "Mic", 0x0 },
1537 { "Front Mic", 0x3 },
1538 { "Line", 0x2 },
1539 { "CD", 0x4 },
1540 },
1541};
1542
1543/* channel source setting (2/6 channel selection for 3-stack) */
1544/* 2ch mode */
1545static struct hda_verb alc880_threestack_ch2_init[] = {
1546 /* set line-in to input, mute it */
1547 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1548 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1549 /* set mic-in to input vref 80%, mute it */
1550 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1551 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1552 { } /* end */
1553};
1554
1555/* 6ch mode */
1556static struct hda_verb alc880_threestack_ch6_init[] = {
1557 /* set line-in to output, unmute it */
1558 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1559 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1560 /* set mic-in to output, unmute it */
1561 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1562 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1563 { } /* end */
1564};
1565
d2a6d7dc 1566static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1567 { 2, alc880_threestack_ch2_init },
1568 { 6, alc880_threestack_ch6_init },
1569};
1570
c8b6bf9b 1571static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1572 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1573 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1574 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1575 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1576 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1577 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1578 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1579 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1580 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1581 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1582 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1583 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1584 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1585 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1586 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1588 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1589 {
1590 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1591 .name = "Channel Mode",
df694daa
KY
1592 .info = alc_ch_mode_info,
1593 .get = alc_ch_mode_get,
1594 .put = alc_ch_mode_put,
e9edcee0
TI
1595 },
1596 { } /* end */
1597};
1598
1599/* capture mixer elements */
f9e336f6
TI
1600static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1601 struct snd_ctl_elem_info *uinfo)
1602{
1603 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1604 struct alc_spec *spec = codec->spec;
1605 int err;
1da177e4 1606
5a9e02e9 1607 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1608 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1609 HDA_INPUT);
1610 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1611 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1612 return err;
1613}
1614
1615static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1616 unsigned int size, unsigned int __user *tlv)
1617{
1618 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1619 struct alc_spec *spec = codec->spec;
1620 int err;
1da177e4 1621
5a9e02e9 1622 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1623 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1624 HDA_INPUT);
1625 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1626 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1627 return err;
1628}
1629
1630typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1631 struct snd_ctl_elem_value *ucontrol);
1632
1633static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1634 struct snd_ctl_elem_value *ucontrol,
1635 getput_call_t func)
1636{
1637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1638 struct alc_spec *spec = codec->spec;
1639 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1640 int err;
1641
5a9e02e9 1642 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1643 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1644 3, 0, HDA_INPUT);
1645 err = func(kcontrol, ucontrol);
5a9e02e9 1646 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1647 return err;
1648}
1649
1650static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1651 struct snd_ctl_elem_value *ucontrol)
1652{
1653 return alc_cap_getput_caller(kcontrol, ucontrol,
1654 snd_hda_mixer_amp_volume_get);
1655}
1656
1657static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1658 struct snd_ctl_elem_value *ucontrol)
1659{
1660 return alc_cap_getput_caller(kcontrol, ucontrol,
1661 snd_hda_mixer_amp_volume_put);
1662}
1663
1664/* capture mixer elements */
1665#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1666
1667static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1668 struct snd_ctl_elem_value *ucontrol)
1669{
1670 return alc_cap_getput_caller(kcontrol, ucontrol,
1671 snd_hda_mixer_amp_switch_get);
1672}
1673
1674static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1675 struct snd_ctl_elem_value *ucontrol)
1676{
1677 return alc_cap_getput_caller(kcontrol, ucontrol,
1678 snd_hda_mixer_amp_switch_put);
1679}
1680
a23b688f 1681#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
1682 { \
1683 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1684 .name = "Capture Switch", \
1685 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1686 .count = num, \
1687 .info = alc_cap_sw_info, \
1688 .get = alc_cap_sw_get, \
1689 .put = alc_cap_sw_put, \
1690 }, \
1691 { \
1692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1693 .name = "Capture Volume", \
1694 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1695 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1696 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1697 .count = num, \
1698 .info = alc_cap_vol_info, \
1699 .get = alc_cap_vol_get, \
1700 .put = alc_cap_vol_put, \
1701 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
1702 }
1703
1704#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
1705 { \
1706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1707 /* .name = "Capture Source", */ \
1708 .name = "Input Source", \
1709 .count = num, \
1710 .info = alc_mux_enum_info, \
1711 .get = alc_mux_enum_get, \
1712 .put = alc_mux_enum_put, \
a23b688f
TI
1713 }
1714
1715#define DEFINE_CAPMIX(num) \
1716static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1717 _DEFINE_CAPMIX(num), \
1718 _DEFINE_CAPSRC(num), \
1719 { } /* end */ \
1720}
1721
1722#define DEFINE_CAPMIX_NOSRC(num) \
1723static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1724 _DEFINE_CAPMIX(num), \
1725 { } /* end */ \
f9e336f6
TI
1726}
1727
1728/* up to three ADCs */
1729DEFINE_CAPMIX(1);
1730DEFINE_CAPMIX(2);
1731DEFINE_CAPMIX(3);
a23b688f
TI
1732DEFINE_CAPMIX_NOSRC(1);
1733DEFINE_CAPMIX_NOSRC(2);
1734DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
1735
1736/*
1737 * ALC880 5-stack model
1738 *
9c7f852e
TI
1739 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1740 * Side = 0x02 (0xd)
e9edcee0
TI
1741 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1742 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1743 */
1744
1745/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1746static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1747 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1748 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1749 { } /* end */
1750};
1751
e9edcee0
TI
1752/* channel source setting (6/8 channel selection for 5-stack) */
1753/* 6ch mode */
1754static struct hda_verb alc880_fivestack_ch6_init[] = {
1755 /* set line-in to input, mute it */
1756 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1757 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1758 { } /* end */
1759};
1760
e9edcee0
TI
1761/* 8ch mode */
1762static struct hda_verb alc880_fivestack_ch8_init[] = {
1763 /* set line-in to output, unmute it */
1764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1765 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1766 { } /* end */
1767};
1768
d2a6d7dc 1769static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1770 { 6, alc880_fivestack_ch6_init },
1771 { 8, alc880_fivestack_ch8_init },
1772};
1773
1774
1775/*
1776 * ALC880 6-stack model
1777 *
9c7f852e
TI
1778 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1779 * Side = 0x05 (0x0f)
e9edcee0
TI
1780 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1781 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1782 */
1783
1784static hda_nid_t alc880_6st_dac_nids[4] = {
1785 /* front, rear, clfe, rear_surr */
1786 0x02, 0x03, 0x04, 0x05
f12ab1e0 1787};
e9edcee0
TI
1788
1789static struct hda_input_mux alc880_6stack_capture_source = {
1790 .num_items = 4,
1791 .items = {
1792 { "Mic", 0x0 },
1793 { "Front Mic", 0x1 },
1794 { "Line", 0x2 },
1795 { "CD", 0x4 },
1796 },
1797};
1798
1799/* fixed 8-channels */
d2a6d7dc 1800static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1801 { 8, NULL },
1802};
1803
c8b6bf9b 1804static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1805 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1806 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1807 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1808 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1809 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1810 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1811 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1812 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1813 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1814 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1815 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1816 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1821 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1822 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
1823 {
1824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1825 .name = "Channel Mode",
df694daa
KY
1826 .info = alc_ch_mode_info,
1827 .get = alc_ch_mode_get,
1828 .put = alc_ch_mode_put,
16ded525
TI
1829 },
1830 { } /* end */
1831};
1832
e9edcee0
TI
1833
1834/*
1835 * ALC880 W810 model
1836 *
1837 * W810 has rear IO for:
1838 * Front (DAC 02)
1839 * Surround (DAC 03)
1840 * Center/LFE (DAC 04)
1841 * Digital out (06)
1842 *
1843 * The system also has a pair of internal speakers, and a headphone jack.
1844 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 1845 *
e9edcee0
TI
1846 * There is a variable resistor to control the speaker or headphone
1847 * volume. This is a hardware-only device without a software API.
1848 *
1849 * Plugging headphones in will disable the internal speakers. This is
1850 * implemented in hardware, not via the driver using jack sense. In
1851 * a similar fashion, plugging into the rear socket marked "front" will
1852 * disable both the speakers and headphones.
1853 *
1854 * For input, there's a microphone jack, and an "audio in" jack.
1855 * These may not do anything useful with this driver yet, because I
1856 * haven't setup any initialization verbs for these yet...
1857 */
1858
1859static hda_nid_t alc880_w810_dac_nids[3] = {
1860 /* front, rear/surround, clfe */
1861 0x02, 0x03, 0x04
16ded525
TI
1862};
1863
e9edcee0 1864/* fixed 6 channels */
d2a6d7dc 1865static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1866 { 6, NULL }
1867};
1868
1869/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1870static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1871 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1872 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1873 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1874 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1875 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1876 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1877 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1878 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1880 { } /* end */
1881};
1882
1883
1884/*
1885 * Z710V model
1886 *
1887 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1888 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1889 * Line = 0x1a
e9edcee0
TI
1890 */
1891
1892static hda_nid_t alc880_z71v_dac_nids[1] = {
1893 0x02
1894};
1895#define ALC880_Z71V_HP_DAC 0x03
1896
1897/* fixed 2 channels */
d2a6d7dc 1898static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1899 { 2, NULL }
1900};
1901
c8b6bf9b 1902static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1903 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1904 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1905 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1906 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1911 { } /* end */
1912};
1913
e9edcee0 1914
e9edcee0
TI
1915/*
1916 * ALC880 F1734 model
1917 *
1918 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1919 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1920 */
1921
1922static hda_nid_t alc880_f1734_dac_nids[1] = {
1923 0x03
1924};
1925#define ALC880_F1734_HP_DAC 0x02
1926
c8b6bf9b 1927static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1928 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1929 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1930 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1936 { } /* end */
1937};
1938
937b4160
TI
1939static struct hda_input_mux alc880_f1734_capture_source = {
1940 .num_items = 2,
1941 .items = {
1942 { "Mic", 0x1 },
1943 { "CD", 0x4 },
1944 },
1945};
1946
e9edcee0 1947
e9edcee0
TI
1948/*
1949 * ALC880 ASUS model
1950 *
1951 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1952 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1953 * Mic = 0x18, Line = 0x1a
1954 */
1955
1956#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1957#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1958
c8b6bf9b 1959static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1965 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1966 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1967 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1968 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1969 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1970 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1971 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1974 {
1975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1976 .name = "Channel Mode",
df694daa
KY
1977 .info = alc_ch_mode_info,
1978 .get = alc_ch_mode_get,
1979 .put = alc_ch_mode_put,
16ded525
TI
1980 },
1981 { } /* end */
1982};
e9edcee0 1983
e9edcee0
TI
1984/*
1985 * ALC880 ASUS W1V model
1986 *
1987 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1988 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1989 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1990 */
1991
1992/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1993static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1994 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1995 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1996 { } /* end */
1997};
1998
df694daa
KY
1999/* TCL S700 */
2000static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2002 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2005 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2009 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2010 { } /* end */
2011};
2012
ccc656ce
KY
2013/* Uniwill */
2014static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2015 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2016 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2017 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2018 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2019 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2020 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2021 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2022 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2023 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2024 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2025 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2026 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2028 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2029 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2031 {
2032 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2033 .name = "Channel Mode",
2034 .info = alc_ch_mode_info,
2035 .get = alc_ch_mode_get,
2036 .put = alc_ch_mode_put,
2037 },
2038 { } /* end */
2039};
2040
2cf9f0fc
TD
2041static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2042 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2043 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2045 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
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("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2049 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2050 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2051 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2052 { } /* end */
2053};
2054
ccc656ce 2055static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2056 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2057 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2059 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2062 { } /* end */
2063};
2064
2134ea4f
TI
2065/*
2066 * virtual master controls
2067 */
2068
2069/*
2070 * slave controls for virtual master
2071 */
2072static const char *alc_slave_vols[] = {
2073 "Front Playback Volume",
2074 "Surround Playback Volume",
2075 "Center Playback Volume",
2076 "LFE Playback Volume",
2077 "Side Playback Volume",
2078 "Headphone Playback Volume",
2079 "Speaker Playback Volume",
2080 "Mono Playback Volume",
2134ea4f 2081 "Line-Out Playback Volume",
26f5df26 2082 "PCM Playback Volume",
2134ea4f
TI
2083 NULL,
2084};
2085
2086static const char *alc_slave_sws[] = {
2087 "Front Playback Switch",
2088 "Surround Playback Switch",
2089 "Center Playback Switch",
2090 "LFE Playback Switch",
2091 "Side Playback Switch",
2092 "Headphone Playback Switch",
2093 "Speaker Playback Switch",
2094 "Mono Playback Switch",
edb54a55 2095 "IEC958 Playback Switch",
2134ea4f
TI
2096 NULL,
2097};
2098
1da177e4 2099/*
e9edcee0 2100 * build control elements
1da177e4 2101 */
603c4019
TI
2102
2103static void alc_free_kctls(struct hda_codec *codec);
2104
45bdd1c1
TI
2105/* additional beep mixers; the actual parameters are overwritten at build */
2106static struct snd_kcontrol_new alc_beep_mixer[] = {
2107 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2108 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2109 { } /* end */
2110};
2111
1da177e4
LT
2112static int alc_build_controls(struct hda_codec *codec)
2113{
2114 struct alc_spec *spec = codec->spec;
2115 int err;
2116 int i;
2117
2118 for (i = 0; i < spec->num_mixers; i++) {
2119 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2120 if (err < 0)
2121 return err;
2122 }
f9e336f6
TI
2123 if (spec->cap_mixer) {
2124 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2125 if (err < 0)
2126 return err;
2127 }
1da177e4 2128 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2129 err = snd_hda_create_spdif_out_ctls(codec,
2130 spec->multiout.dig_out_nid);
1da177e4
LT
2131 if (err < 0)
2132 return err;
e64f14f4
TI
2133 if (!spec->no_analog) {
2134 err = snd_hda_create_spdif_share_sw(codec,
2135 &spec->multiout);
2136 if (err < 0)
2137 return err;
2138 spec->multiout.share_spdif = 1;
2139 }
1da177e4
LT
2140 }
2141 if (spec->dig_in_nid) {
2142 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2143 if (err < 0)
2144 return err;
2145 }
2134ea4f 2146
45bdd1c1
TI
2147 /* create beep controls if needed */
2148 if (spec->beep_amp) {
2149 struct snd_kcontrol_new *knew;
2150 for (knew = alc_beep_mixer; knew->name; knew++) {
2151 struct snd_kcontrol *kctl;
2152 kctl = snd_ctl_new1(knew, codec);
2153 if (!kctl)
2154 return -ENOMEM;
2155 kctl->private_value = spec->beep_amp;
2156 err = snd_hda_ctl_add(codec, kctl);
2157 if (err < 0)
2158 return err;
2159 }
2160 }
2161
2134ea4f 2162 /* if we have no master control, let's create it */
e64f14f4
TI
2163 if (!spec->no_analog &&
2164 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2165 unsigned int vmaster_tlv[4];
2134ea4f 2166 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2167 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2168 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2169 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2170 if (err < 0)
2171 return err;
2172 }
e64f14f4
TI
2173 if (!spec->no_analog &&
2174 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2175 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2176 NULL, alc_slave_sws);
2177 if (err < 0)
2178 return err;
2179 }
2180
603c4019 2181 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
2182 return 0;
2183}
2184
e9edcee0 2185
1da177e4
LT
2186/*
2187 * initialize the codec volumes, etc
2188 */
2189
e9edcee0
TI
2190/*
2191 * generic initialization of ADC, input mixers and output mixers
2192 */
2193static struct hda_verb alc880_volume_init_verbs[] = {
2194 /*
2195 * Unmute ADC0-2 and set the default input to mic-in
2196 */
71fe7b82 2197 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2199 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2203
e9edcee0
TI
2204 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2205 * mixer widget
9c7f852e
TI
2206 * Note: PASD motherboards uses the Line In 2 as the input for front
2207 * panel mic (mic 2)
1da177e4 2208 */
e9edcee0 2209 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2215 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2216 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2217
e9edcee0
TI
2218 /*
2219 * Set up output mixers (0x0c - 0x0f)
1da177e4 2220 */
e9edcee0
TI
2221 /* set vol=0 to output mixers */
2222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2225 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2226 /* set up input amps for analog loopback */
2227 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2230 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2231 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2235 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2236
2237 { }
2238};
2239
e9edcee0
TI
2240/*
2241 * 3-stack pin configuration:
2242 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2243 */
2244static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2245 /*
2246 * preset connection lists of input pins
2247 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2248 */
2249 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2250 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2251 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2252
2253 /*
2254 * Set pin mode and muting
2255 */
2256 /* set front pin widgets 0x14 for output */
05acb863 2257 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2258 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2262 /* Mic2 (as headphone out) for HP output */
2263 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2264 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2265 /* Line In pin widget for input */
05acb863 2266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2267 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2268 /* Line2 (as front mic) pin widget for input and vref at 80% */
2269 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2270 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2271 /* CD pin widget for input */
05acb863 2272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2273
e9edcee0
TI
2274 { }
2275};
1da177e4 2276
e9edcee0
TI
2277/*
2278 * 5-stack pin configuration:
2279 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2280 * line-in/side = 0x1a, f-mic = 0x1b
2281 */
2282static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2283 /*
2284 * preset connection lists of input pins
2285 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2286 */
e9edcee0
TI
2287 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2288 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2289
e9edcee0
TI
2290 /*
2291 * Set pin mode and muting
1da177e4 2292 */
e9edcee0
TI
2293 /* set pin widgets 0x14-0x17 for output */
2294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2296 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2297 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2298 /* unmute pins for output (no gain on this amp) */
2299 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2301 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303
2304 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2305 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2306 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307 /* Mic2 (as headphone out) for HP output */
2308 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2309 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 /* Line In pin widget for input */
2311 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2312 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2313 /* Line2 (as front mic) pin widget for input and vref at 80% */
2314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2316 /* CD pin widget for input */
2317 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2318
2319 { }
2320};
2321
e9edcee0
TI
2322/*
2323 * W810 pin configuration:
2324 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2325 */
2326static struct hda_verb alc880_pin_w810_init_verbs[] = {
2327 /* hphone/speaker input selector: front DAC */
2328 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2329
05acb863 2330 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2331 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2336
e9edcee0 2337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2338 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2339
1da177e4
LT
2340 { }
2341};
2342
e9edcee0
TI
2343/*
2344 * Z71V pin configuration:
2345 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2346 */
2347static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2348 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2350 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2351 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2352
16ded525 2353 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2354 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2357
2358 { }
2359};
2360
e9edcee0
TI
2361/*
2362 * 6-stack pin configuration:
9c7f852e
TI
2363 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2364 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2365 */
2366static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2367 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2368
16ded525 2369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2374 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2375 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2376 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377
16ded525 2378 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2379 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2380 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2381 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2382 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2383 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2385 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2386 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2387
e9edcee0
TI
2388 { }
2389};
2390
ccc656ce
KY
2391/*
2392 * Uniwill pin configuration:
2393 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2394 * line = 0x1a
2395 */
2396static struct hda_verb alc880_uniwill_init_verbs[] = {
2397 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2398
2399 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2400 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2402 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2403 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2404 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2405 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2406 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2413
2414 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2415 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2417 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2418 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2419 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2420 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2421 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2422 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2423
2424 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2425 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2426
2427 { }
2428};
2429
2430/*
2431* Uniwill P53
ea1fb29a 2432* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2433 */
2434static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2435 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2436
2437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2440 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2441 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2442 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2443 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2444 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2446 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2447 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2448 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2449
2450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2452 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2453 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2454 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2455 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2456
2457 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2458 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2459
2460 { }
2461};
2462
2cf9f0fc
TD
2463static struct hda_verb alc880_beep_init_verbs[] = {
2464 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2465 { }
2466};
2467
458a4fab
TI
2468/* auto-toggle front mic */
2469static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2470{
2471 unsigned int present;
2472 unsigned char bits;
ccc656ce
KY
2473
2474 present = snd_hda_codec_read(codec, 0x18, 0,
2475 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2476 bits = present ? HDA_AMP_MUTE : 0;
2477 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2478}
2479
a9fd4f3f 2480static void alc880_uniwill_init_hook(struct hda_codec *codec)
458a4fab 2481{
a9fd4f3f
TI
2482 struct alc_spec *spec = codec->spec;
2483
2484 spec->autocfg.hp_pins[0] = 0x14;
2485 spec->autocfg.speaker_pins[0] = 0x15;
2486 spec->autocfg.speaker_pins[0] = 0x16;
2487 alc_automute_amp(codec);
458a4fab 2488 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2489}
2490
2491static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2492 unsigned int res)
2493{
2494 /* Looks like the unsol event is incompatible with the standard
2495 * definition. 4bit tag is placed at 28 bit!
2496 */
458a4fab 2497 switch (res >> 28) {
458a4fab
TI
2498 case ALC880_MIC_EVENT:
2499 alc880_uniwill_mic_automute(codec);
2500 break;
a9fd4f3f
TI
2501 default:
2502 alc_automute_amp_unsol_event(codec, res);
2503 break;
458a4fab 2504 }
ccc656ce
KY
2505}
2506
a9fd4f3f 2507static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
ccc656ce 2508{
a9fd4f3f 2509 struct alc_spec *spec = codec->spec;
ccc656ce 2510
a9fd4f3f
TI
2511 spec->autocfg.hp_pins[0] = 0x14;
2512 spec->autocfg.speaker_pins[0] = 0x15;
2513 alc_automute_amp(codec);
ccc656ce
KY
2514}
2515
2516static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2517{
2518 unsigned int present;
ea1fb29a 2519
ccc656ce 2520 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2521 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2522 present &= HDA_AMP_VOLMASK;
2523 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2524 HDA_AMP_VOLMASK, present);
2525 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2526 HDA_AMP_VOLMASK, present);
ccc656ce 2527}
47fd830a 2528
ccc656ce
KY
2529static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2530 unsigned int res)
2531{
2532 /* Looks like the unsol event is incompatible with the standard
2533 * definition. 4bit tag is placed at 28 bit!
2534 */
f12ab1e0 2535 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 2536 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
2537 else
2538 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
2539}
2540
e9edcee0
TI
2541/*
2542 * F1734 pin configuration:
2543 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2544 */
2545static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2546 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2547 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2548 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2549 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2550 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2551
e9edcee0 2552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2556
e9edcee0
TI
2557 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2558 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2559 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2560 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2562 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2563 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2564 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2565 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2566
937b4160
TI
2567 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2568 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2569
dfc0ff62
TI
2570 { }
2571};
2572
e9edcee0
TI
2573/*
2574 * ASUS pin configuration:
2575 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2576 */
2577static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2578 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2579 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2580 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2581 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2582
2583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2584 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2587 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2589 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2591
2592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2593 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2595 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2596 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2598 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2599 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2600 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2601
e9edcee0
TI
2602 { }
2603};
16ded525 2604
e9edcee0 2605/* Enable GPIO mask and set output */
bc9f98a9
KY
2606#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2607#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
2608
2609/* Clevo m520g init */
2610static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2611 /* headphone output */
2612 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2613 /* line-out */
2614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2616 /* Line-in */
2617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2619 /* CD */
2620 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2621 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2622 /* Mic1 (rear panel) */
2623 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2625 /* Mic2 (front panel) */
2626 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2627 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2628 /* headphone */
2629 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2630 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2631 /* change to EAPD mode */
2632 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2633 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2634
2635 { }
16ded525
TI
2636};
2637
df694daa 2638static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2639 /* change to EAPD mode */
2640 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2641 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2642
df694daa
KY
2643 /* Headphone output */
2644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2645 /* Front output*/
2646 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2647 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2648
2649 /* Line In pin widget for input */
2650 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2651 /* CD pin widget for input */
2652 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2653 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2655
2656 /* change to EAPD mode */
2657 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2658 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2659
2660 { }
2661};
16ded525 2662
e9edcee0 2663/*
ae6b813a
TI
2664 * LG m1 express dual
2665 *
2666 * Pin assignment:
2667 * Rear Line-In/Out (blue): 0x14
2668 * Build-in Mic-In: 0x15
2669 * Speaker-out: 0x17
2670 * HP-Out (green): 0x1b
2671 * Mic-In/Out (red): 0x19
2672 * SPDIF-Out: 0x1e
2673 */
2674
2675/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2676static hda_nid_t alc880_lg_dac_nids[3] = {
2677 0x05, 0x02, 0x03
2678};
2679
2680/* seems analog CD is not working */
2681static struct hda_input_mux alc880_lg_capture_source = {
2682 .num_items = 3,
2683 .items = {
2684 { "Mic", 0x1 },
2685 { "Line", 0x5 },
2686 { "Internal Mic", 0x6 },
2687 },
2688};
2689
2690/* 2,4,6 channel modes */
2691static struct hda_verb alc880_lg_ch2_init[] = {
2692 /* set line-in and mic-in to input */
2693 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2694 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2695 { }
2696};
2697
2698static struct hda_verb alc880_lg_ch4_init[] = {
2699 /* set line-in to out and mic-in to input */
2700 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2701 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2702 { }
2703};
2704
2705static struct hda_verb alc880_lg_ch6_init[] = {
2706 /* set line-in and mic-in to output */
2707 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2708 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2709 { }
2710};
2711
2712static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2713 { 2, alc880_lg_ch2_init },
2714 { 4, alc880_lg_ch4_init },
2715 { 6, alc880_lg_ch6_init },
2716};
2717
2718static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2720 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2721 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2724 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2725 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2726 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2730 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2731 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2732 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2733 {
2734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2735 .name = "Channel Mode",
2736 .info = alc_ch_mode_info,
2737 .get = alc_ch_mode_get,
2738 .put = alc_ch_mode_put,
2739 },
2740 { } /* end */
2741};
2742
2743static struct hda_verb alc880_lg_init_verbs[] = {
2744 /* set capture source to mic-in */
2745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2747 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2748 /* mute all amp mixer inputs */
2749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2752 /* line-in to input */
2753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2755 /* built-in mic */
2756 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2758 /* speaker-out */
2759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2760 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2761 /* mic-in to input */
2762 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2765 /* HP-out */
2766 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2767 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2768 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2769 /* jack sense */
a9fd4f3f 2770 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
2771 { }
2772};
2773
2774/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 2775static void alc880_lg_init_hook(struct hda_codec *codec)
ae6b813a 2776{
a9fd4f3f 2777 struct alc_spec *spec = codec->spec;
ae6b813a 2778
a9fd4f3f
TI
2779 spec->autocfg.hp_pins[0] = 0x1b;
2780 spec->autocfg.speaker_pins[0] = 0x17;
2781 alc_automute_amp(codec);
ae6b813a
TI
2782}
2783
d681518a
TI
2784/*
2785 * LG LW20
2786 *
2787 * Pin assignment:
2788 * Speaker-out: 0x14
2789 * Mic-In: 0x18
e4f41da9
CM
2790 * Built-in Mic-In: 0x19
2791 * Line-In: 0x1b
2792 * HP-Out: 0x1a
d681518a
TI
2793 * SPDIF-Out: 0x1e
2794 */
2795
d681518a 2796static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2797 .num_items = 3,
d681518a
TI
2798 .items = {
2799 { "Mic", 0x0 },
2800 { "Internal Mic", 0x1 },
e4f41da9 2801 { "Line In", 0x2 },
d681518a
TI
2802 },
2803};
2804
0a8c5da3
CM
2805#define alc880_lg_lw_modes alc880_threestack_modes
2806
d681518a 2807static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2809 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2810 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2811 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2812 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2813 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2814 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2815 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2816 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2817 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2818 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2820 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2821 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2822 {
2823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2824 .name = "Channel Mode",
2825 .info = alc_ch_mode_info,
2826 .get = alc_ch_mode_get,
2827 .put = alc_ch_mode_put,
2828 },
d681518a
TI
2829 { } /* end */
2830};
2831
2832static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2833 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2834 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2835 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2836
d681518a
TI
2837 /* set capture source to mic-in */
2838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2839 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2840 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2842 /* speaker-out */
2843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2845 /* HP-out */
d681518a
TI
2846 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 /* mic-in to input */
2849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2850 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2851 /* built-in mic */
2852 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2853 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2854 /* jack sense */
a9fd4f3f 2855 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
2856 { }
2857};
2858
2859/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 2860static void alc880_lg_lw_init_hook(struct hda_codec *codec)
d681518a 2861{
a9fd4f3f 2862 struct alc_spec *spec = codec->spec;
d681518a 2863
a9fd4f3f
TI
2864 spec->autocfg.hp_pins[0] = 0x1b;
2865 spec->autocfg.speaker_pins[0] = 0x14;
2866 alc_automute_amp(codec);
d681518a
TI
2867}
2868
df99cd33
TI
2869static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2870 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2871 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2874 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2875 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2876 { } /* end */
2877};
2878
2879static struct hda_input_mux alc880_medion_rim_capture_source = {
2880 .num_items = 2,
2881 .items = {
2882 { "Mic", 0x0 },
2883 { "Internal Mic", 0x1 },
2884 },
2885};
2886
2887static struct hda_verb alc880_medion_rim_init_verbs[] = {
2888 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2889
2890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2892
2893 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2894 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2895 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2896 /* Mic2 (as headphone out) for HP output */
2897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2899 /* Internal Speaker */
2900 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2901 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2902
2903 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2904 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2905
2906 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2907 { }
2908};
2909
2910/* toggle speaker-output according to the hp-jack state */
2911static void alc880_medion_rim_automute(struct hda_codec *codec)
2912{
a9fd4f3f
TI
2913 struct alc_spec *spec = codec->spec;
2914 alc_automute_amp(codec);
2915 /* toggle EAPD */
2916 if (spec->jack_present)
df99cd33
TI
2917 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2918 else
2919 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2920}
2921
2922static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2923 unsigned int res)
2924{
2925 /* Looks like the unsol event is incompatible with the standard
2926 * definition. 4bit tag is placed at 28 bit!
2927 */
2928 if ((res >> 28) == ALC880_HP_EVENT)
2929 alc880_medion_rim_automute(codec);
2930}
2931
a9fd4f3f
TI
2932static void alc880_medion_rim_init_hook(struct hda_codec *codec)
2933{
2934 struct alc_spec *spec = codec->spec;
2935
2936 spec->autocfg.hp_pins[0] = 0x14;
2937 spec->autocfg.speaker_pins[0] = 0x1b;
2938 alc880_medion_rim_automute(codec);
2939}
2940
cb53c626
TI
2941#ifdef CONFIG_SND_HDA_POWER_SAVE
2942static struct hda_amp_list alc880_loopbacks[] = {
2943 { 0x0b, HDA_INPUT, 0 },
2944 { 0x0b, HDA_INPUT, 1 },
2945 { 0x0b, HDA_INPUT, 2 },
2946 { 0x0b, HDA_INPUT, 3 },
2947 { 0x0b, HDA_INPUT, 4 },
2948 { } /* end */
2949};
2950
2951static struct hda_amp_list alc880_lg_loopbacks[] = {
2952 { 0x0b, HDA_INPUT, 1 },
2953 { 0x0b, HDA_INPUT, 6 },
2954 { 0x0b, HDA_INPUT, 7 },
2955 { } /* end */
2956};
2957#endif
2958
ae6b813a
TI
2959/*
2960 * Common callbacks
e9edcee0
TI
2961 */
2962
1da177e4
LT
2963static int alc_init(struct hda_codec *codec)
2964{
2965 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2966 unsigned int i;
2967
2c3bf9ab 2968 alc_fix_pll(codec);
4a79ba34 2969 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 2970
e9edcee0
TI
2971 for (i = 0; i < spec->num_init_verbs; i++)
2972 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2973
2974 if (spec->init_hook)
2975 spec->init_hook(codec);
2976
1da177e4
LT
2977 return 0;
2978}
2979
ae6b813a
TI
2980static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2981{
2982 struct alc_spec *spec = codec->spec;
2983
2984 if (spec->unsol_event)
2985 spec->unsol_event(codec, res);
2986}
2987
cb53c626
TI
2988#ifdef CONFIG_SND_HDA_POWER_SAVE
2989static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2990{
2991 struct alc_spec *spec = codec->spec;
2992 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2993}
2994#endif
2995
1da177e4
LT
2996/*
2997 * Analog playback callbacks
2998 */
2999static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3000 struct hda_codec *codec,
c8b6bf9b 3001 struct snd_pcm_substream *substream)
1da177e4
LT
3002{
3003 struct alc_spec *spec = codec->spec;
9a08160b
TI
3004 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3005 hinfo);
1da177e4
LT
3006}
3007
3008static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3009 struct hda_codec *codec,
3010 unsigned int stream_tag,
3011 unsigned int format,
c8b6bf9b 3012 struct snd_pcm_substream *substream)
1da177e4
LT
3013{
3014 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3015 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3016 stream_tag, format, substream);
1da177e4
LT
3017}
3018
3019static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3020 struct hda_codec *codec,
c8b6bf9b 3021 struct snd_pcm_substream *substream)
1da177e4
LT
3022{
3023 struct alc_spec *spec = codec->spec;
3024 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3025}
3026
3027/*
3028 * Digital out
3029 */
3030static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3031 struct hda_codec *codec,
c8b6bf9b 3032 struct snd_pcm_substream *substream)
1da177e4
LT
3033{
3034 struct alc_spec *spec = codec->spec;
3035 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3036}
3037
6b97eb45
TI
3038static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3039 struct hda_codec *codec,
3040 unsigned int stream_tag,
3041 unsigned int format,
3042 struct snd_pcm_substream *substream)
3043{
3044 struct alc_spec *spec = codec->spec;
3045 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3046 stream_tag, format, substream);
3047}
3048
9b5f12e5
TI
3049static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3050 struct hda_codec *codec,
3051 struct snd_pcm_substream *substream)
3052{
3053 struct alc_spec *spec = codec->spec;
3054 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3055}
3056
1da177e4
LT
3057static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3058 struct hda_codec *codec,
c8b6bf9b 3059 struct snd_pcm_substream *substream)
1da177e4
LT
3060{
3061 struct alc_spec *spec = codec->spec;
3062 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3063}
3064
3065/*
3066 * Analog capture
3067 */
6330079f 3068static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3069 struct hda_codec *codec,
3070 unsigned int stream_tag,
3071 unsigned int format,
c8b6bf9b 3072 struct snd_pcm_substream *substream)
1da177e4
LT
3073{
3074 struct alc_spec *spec = codec->spec;
3075
6330079f 3076 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3077 stream_tag, 0, format);
3078 return 0;
3079}
3080
6330079f 3081static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3082 struct hda_codec *codec,
c8b6bf9b 3083 struct snd_pcm_substream *substream)
1da177e4
LT
3084{
3085 struct alc_spec *spec = codec->spec;
3086
888afa15
TI
3087 snd_hda_codec_cleanup_stream(codec,
3088 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3089 return 0;
3090}
3091
3092
3093/*
3094 */
3095static struct hda_pcm_stream alc880_pcm_analog_playback = {
3096 .substreams = 1,
3097 .channels_min = 2,
3098 .channels_max = 8,
e9edcee0 3099 /* NID is set in alc_build_pcms */
1da177e4
LT
3100 .ops = {
3101 .open = alc880_playback_pcm_open,
3102 .prepare = alc880_playback_pcm_prepare,
3103 .cleanup = alc880_playback_pcm_cleanup
3104 },
3105};
3106
3107static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3108 .substreams = 1,
3109 .channels_min = 2,
3110 .channels_max = 2,
3111 /* NID is set in alc_build_pcms */
3112};
3113
3114static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3115 .substreams = 1,
3116 .channels_min = 2,
3117 .channels_max = 2,
3118 /* NID is set in alc_build_pcms */
3119};
3120
3121static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3122 .substreams = 2, /* can be overridden */
1da177e4
LT
3123 .channels_min = 2,
3124 .channels_max = 2,
e9edcee0 3125 /* NID is set in alc_build_pcms */
1da177e4 3126 .ops = {
6330079f
TI
3127 .prepare = alc880_alt_capture_pcm_prepare,
3128 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3129 },
3130};
3131
3132static struct hda_pcm_stream alc880_pcm_digital_playback = {
3133 .substreams = 1,
3134 .channels_min = 2,
3135 .channels_max = 2,
3136 /* NID is set in alc_build_pcms */
3137 .ops = {
3138 .open = alc880_dig_playback_pcm_open,
6b97eb45 3139 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3140 .prepare = alc880_dig_playback_pcm_prepare,
3141 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3142 },
3143};
3144
3145static struct hda_pcm_stream alc880_pcm_digital_capture = {
3146 .substreams = 1,
3147 .channels_min = 2,
3148 .channels_max = 2,
3149 /* NID is set in alc_build_pcms */
3150};
3151
4c5186ed 3152/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3153static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3154 .substreams = 0,
3155 .channels_min = 0,
3156 .channels_max = 0,
3157};
3158
1da177e4
LT
3159static int alc_build_pcms(struct hda_codec *codec)
3160{
3161 struct alc_spec *spec = codec->spec;
3162 struct hda_pcm *info = spec->pcm_rec;
3163 int i;
3164
3165 codec->num_pcms = 1;
3166 codec->pcm_info = info;
3167
e64f14f4
TI
3168 if (spec->no_analog)
3169 goto skip_analog;
3170
1da177e4 3171 info->name = spec->stream_name_analog;
4a471b7d 3172 if (spec->stream_analog_playback) {
da3cec35
TI
3173 if (snd_BUG_ON(!spec->multiout.dac_nids))
3174 return -EINVAL;
4a471b7d
TI
3175 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3176 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3177 }
3178 if (spec->stream_analog_capture) {
da3cec35
TI
3179 if (snd_BUG_ON(!spec->adc_nids))
3180 return -EINVAL;
4a471b7d
TI
3181 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3182 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3183 }
3184
3185 if (spec->channel_mode) {
3186 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3187 for (i = 0; i < spec->num_channel_mode; i++) {
3188 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3189 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3190 }
1da177e4
LT
3191 }
3192 }
3193
e64f14f4 3194 skip_analog:
e08a007d 3195 /* SPDIF for stream index #1 */
1da177e4 3196 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 3197 codec->num_pcms = 2;
b25c9da1 3198 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3199 info = spec->pcm_rec + 1;
1da177e4 3200 info->name = spec->stream_name_digital;
8c441982
TI
3201 if (spec->dig_out_type)
3202 info->pcm_type = spec->dig_out_type;
3203 else
3204 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3205 if (spec->multiout.dig_out_nid &&
3206 spec->stream_digital_playback) {
1da177e4
LT
3207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3208 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3209 }
4a471b7d
TI
3210 if (spec->dig_in_nid &&
3211 spec->stream_digital_capture) {
1da177e4
LT
3212 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3213 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3214 }
963f803f
TI
3215 /* FIXME: do we need this for all Realtek codec models? */
3216 codec->spdif_status_reset = 1;
1da177e4
LT
3217 }
3218
e64f14f4
TI
3219 if (spec->no_analog)
3220 return 0;
3221
e08a007d
TI
3222 /* If the use of more than one ADC is requested for the current
3223 * model, configure a second analog capture-only PCM.
3224 */
3225 /* Additional Analaog capture for index #2 */
6330079f
TI
3226 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3227 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3228 codec->num_pcms = 3;
c06134d7 3229 info = spec->pcm_rec + 2;
e08a007d 3230 info->name = spec->stream_name_analog;
6330079f
TI
3231 if (spec->alt_dac_nid) {
3232 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3233 *spec->stream_analog_alt_playback;
3234 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3235 spec->alt_dac_nid;
3236 } else {
3237 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3238 alc_pcm_null_stream;
3239 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3240 }
3241 if (spec->num_adc_nids > 1) {
3242 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3243 *spec->stream_analog_alt_capture;
3244 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3245 spec->adc_nids[1];
3246 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3247 spec->num_adc_nids - 1;
3248 } else {
3249 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3250 alc_pcm_null_stream;
3251 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3252 }
3253 }
3254
1da177e4
LT
3255 return 0;
3256}
3257
603c4019
TI
3258static void alc_free_kctls(struct hda_codec *codec)
3259{
3260 struct alc_spec *spec = codec->spec;
3261
3262 if (spec->kctls.list) {
3263 struct snd_kcontrol_new *kctl = spec->kctls.list;
3264 int i;
3265 for (i = 0; i < spec->kctls.used; i++)
3266 kfree(kctl[i].name);
3267 }
3268 snd_array_free(&spec->kctls);
3269}
3270
1da177e4
LT
3271static void alc_free(struct hda_codec *codec)
3272{
e9edcee0 3273 struct alc_spec *spec = codec->spec;
e9edcee0 3274
f12ab1e0 3275 if (!spec)
e9edcee0
TI
3276 return;
3277
603c4019 3278 alc_free_kctls(codec);
e9edcee0 3279 kfree(spec);
680cd536 3280 snd_hda_detach_beep_device(codec);
1da177e4
LT
3281}
3282
e044c39a 3283#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3284static int alc_resume(struct hda_codec *codec)
3285{
e044c39a
TI
3286 codec->patch_ops.init(codec);
3287 snd_hda_codec_resume_amp(codec);
3288 snd_hda_codec_resume_cache(codec);
3289 return 0;
3290}
e044c39a
TI
3291#endif
3292
1da177e4
LT
3293/*
3294 */
3295static struct hda_codec_ops alc_patch_ops = {
3296 .build_controls = alc_build_controls,
3297 .build_pcms = alc_build_pcms,
3298 .init = alc_init,
3299 .free = alc_free,
ae6b813a 3300 .unsol_event = alc_unsol_event,
e044c39a
TI
3301#ifdef SND_HDA_NEEDS_RESUME
3302 .resume = alc_resume,
3303#endif
cb53c626
TI
3304#ifdef CONFIG_SND_HDA_POWER_SAVE
3305 .check_power_status = alc_check_power_status,
3306#endif
1da177e4
LT
3307};
3308
2fa522be
TI
3309
3310/*
3311 * Test configuration for debugging
3312 *
3313 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3314 * enum controls.
3315 */
3316#ifdef CONFIG_SND_DEBUG
3317static hda_nid_t alc880_test_dac_nids[4] = {
3318 0x02, 0x03, 0x04, 0x05
3319};
3320
3321static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3322 .num_items = 7,
2fa522be
TI
3323 .items = {
3324 { "In-1", 0x0 },
3325 { "In-2", 0x1 },
3326 { "In-3", 0x2 },
3327 { "In-4", 0x3 },
3328 { "CD", 0x4 },
ae6b813a
TI
3329 { "Front", 0x5 },
3330 { "Surround", 0x6 },
2fa522be
TI
3331 },
3332};
3333
d2a6d7dc 3334static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3335 { 2, NULL },
fd2c326d 3336 { 4, NULL },
2fa522be 3337 { 6, NULL },
fd2c326d 3338 { 8, NULL },
2fa522be
TI
3339};
3340
9c7f852e
TI
3341static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3342 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3343{
3344 static char *texts[] = {
3345 "N/A", "Line Out", "HP Out",
3346 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3347 };
3348 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3349 uinfo->count = 1;
3350 uinfo->value.enumerated.items = 8;
3351 if (uinfo->value.enumerated.item >= 8)
3352 uinfo->value.enumerated.item = 7;
3353 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3354 return 0;
3355}
3356
9c7f852e
TI
3357static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3358 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3359{
3360 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3361 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3362 unsigned int pin_ctl, item = 0;
3363
3364 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3365 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3366 if (pin_ctl & AC_PINCTL_OUT_EN) {
3367 if (pin_ctl & AC_PINCTL_HP_EN)
3368 item = 2;
3369 else
3370 item = 1;
3371 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3372 switch (pin_ctl & AC_PINCTL_VREFEN) {
3373 case AC_PINCTL_VREF_HIZ: item = 3; break;
3374 case AC_PINCTL_VREF_50: item = 4; break;
3375 case AC_PINCTL_VREF_GRD: item = 5; break;
3376 case AC_PINCTL_VREF_80: item = 6; break;
3377 case AC_PINCTL_VREF_100: item = 7; break;
3378 }
3379 }
3380 ucontrol->value.enumerated.item[0] = item;
3381 return 0;
3382}
3383
9c7f852e
TI
3384static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3385 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3386{
3387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3388 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3389 static unsigned int ctls[] = {
3390 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3391 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3392 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3393 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3394 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3395 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3396 };
3397 unsigned int old_ctl, new_ctl;
3398
3399 old_ctl = snd_hda_codec_read(codec, nid, 0,
3400 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3401 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3402 if (old_ctl != new_ctl) {
82beb8fd
TI
3403 int val;
3404 snd_hda_codec_write_cache(codec, nid, 0,
3405 AC_VERB_SET_PIN_WIDGET_CONTROL,
3406 new_ctl);
47fd830a
TI
3407 val = ucontrol->value.enumerated.item[0] >= 3 ?
3408 HDA_AMP_MUTE : 0;
3409 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3410 HDA_AMP_MUTE, val);
2fa522be
TI
3411 return 1;
3412 }
3413 return 0;
3414}
3415
9c7f852e
TI
3416static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3417 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3418{
3419 static char *texts[] = {
3420 "Front", "Surround", "CLFE", "Side"
3421 };
3422 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3423 uinfo->count = 1;
3424 uinfo->value.enumerated.items = 4;
3425 if (uinfo->value.enumerated.item >= 4)
3426 uinfo->value.enumerated.item = 3;
3427 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3428 return 0;
3429}
3430
9c7f852e
TI
3431static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3432 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3433{
3434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3435 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3436 unsigned int sel;
3437
3438 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3439 ucontrol->value.enumerated.item[0] = sel & 3;
3440 return 0;
3441}
3442
9c7f852e
TI
3443static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3444 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3445{
3446 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3447 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3448 unsigned int sel;
3449
3450 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3451 if (ucontrol->value.enumerated.item[0] != sel) {
3452 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3453 snd_hda_codec_write_cache(codec, nid, 0,
3454 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3455 return 1;
3456 }
3457 return 0;
3458}
3459
3460#define PIN_CTL_TEST(xname,nid) { \
3461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3462 .name = xname, \
3463 .info = alc_test_pin_ctl_info, \
3464 .get = alc_test_pin_ctl_get, \
3465 .put = alc_test_pin_ctl_put, \
3466 .private_value = nid \
3467 }
3468
3469#define PIN_SRC_TEST(xname,nid) { \
3470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3471 .name = xname, \
3472 .info = alc_test_pin_src_info, \
3473 .get = alc_test_pin_src_get, \
3474 .put = alc_test_pin_src_put, \
3475 .private_value = nid \
3476 }
3477
c8b6bf9b 3478static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3479 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3480 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3481 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3482 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3483 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3484 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3485 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3486 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3487 PIN_CTL_TEST("Front Pin Mode", 0x14),
3488 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3489 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3490 PIN_CTL_TEST("Side Pin Mode", 0x17),
3491 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3492 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3493 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3494 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3495 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3496 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3497 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3498 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3499 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3500 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3501 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3502 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3503 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3504 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3505 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3506 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3507 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3508 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3509 {
3510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3511 .name = "Channel Mode",
df694daa
KY
3512 .info = alc_ch_mode_info,
3513 .get = alc_ch_mode_get,
3514 .put = alc_ch_mode_put,
2fa522be
TI
3515 },
3516 { } /* end */
3517};
3518
3519static struct hda_verb alc880_test_init_verbs[] = {
3520 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3523 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3524 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3525 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3526 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3527 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3529 /* Vol output for 0x0c-0x0f */
05acb863
TI
3530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3532 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3534 /* Set output pins 0x14-0x17 */
05acb863
TI
3535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3539 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3544 /* Set input pins 0x18-0x1c */
16ded525
TI
3545 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3546 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3550 /* Mute input pins 0x18-0x1b */
05acb863
TI
3551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3552 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3555 /* ADC set up */
05acb863 3556 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3557 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3561 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3562 /* Analog input/passthru */
3563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3568 { }
3569};
3570#endif
3571
1da177e4
LT
3572/*
3573 */
3574
f5fcc13c
TI
3575static const char *alc880_models[ALC880_MODEL_LAST] = {
3576 [ALC880_3ST] = "3stack",
3577 [ALC880_TCL_S700] = "tcl",
3578 [ALC880_3ST_DIG] = "3stack-digout",
3579 [ALC880_CLEVO] = "clevo",
3580 [ALC880_5ST] = "5stack",
3581 [ALC880_5ST_DIG] = "5stack-digout",
3582 [ALC880_W810] = "w810",
3583 [ALC880_Z71V] = "z71v",
3584 [ALC880_6ST] = "6stack",
3585 [ALC880_6ST_DIG] = "6stack-digout",
3586 [ALC880_ASUS] = "asus",
3587 [ALC880_ASUS_W1V] = "asus-w1v",
3588 [ALC880_ASUS_DIG] = "asus-dig",
3589 [ALC880_ASUS_DIG2] = "asus-dig2",
3590 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3591 [ALC880_UNIWILL_P53] = "uniwill-p53",
3592 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3593 [ALC880_F1734] = "F1734",
3594 [ALC880_LG] = "lg",
3595 [ALC880_LG_LW] = "lg-lw",
df99cd33 3596 [ALC880_MEDION_RIM] = "medion",
2fa522be 3597#ifdef CONFIG_SND_DEBUG
f5fcc13c 3598 [ALC880_TEST] = "test",
2fa522be 3599#endif
f5fcc13c
TI
3600 [ALC880_AUTO] = "auto",
3601};
3602
3603static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3604 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3605 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3606 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3607 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3608 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3609 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3610 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3611 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3612 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3613 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3614 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3615 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3616 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3617 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3618 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3619 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3620 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3621 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3622 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3623 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3624 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3625 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3626 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3627 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3628 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 3629 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3630 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3631 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3632 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3633 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3634 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3635 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3636 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3637 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3638 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3639 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3640 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3641 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3642 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3643 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3644 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3645 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3646 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3647 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3648 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3649 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3650 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3651 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3652 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3653 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3654 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3655 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3656 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3657 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3658 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3659 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3660 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3661 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3662 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3663 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3664 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3665 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3666 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3667 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3668 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3669 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3670 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3671 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
3672 /* default Intel */
3673 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
3674 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3675 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3676 {}
3677};
3678
16ded525 3679/*
df694daa 3680 * ALC880 codec presets
16ded525 3681 */
16ded525
TI
3682static struct alc_config_preset alc880_presets[] = {
3683 [ALC880_3ST] = {
e9edcee0 3684 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3685 .init_verbs = { alc880_volume_init_verbs,
3686 alc880_pin_3stack_init_verbs },
16ded525 3687 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3688 .dac_nids = alc880_dac_nids,
16ded525
TI
3689 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3690 .channel_mode = alc880_threestack_modes,
4e195a7b 3691 .need_dac_fix = 1,
16ded525
TI
3692 .input_mux = &alc880_capture_source,
3693 },
3694 [ALC880_3ST_DIG] = {
e9edcee0 3695 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3696 .init_verbs = { alc880_volume_init_verbs,
3697 alc880_pin_3stack_init_verbs },
16ded525 3698 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3699 .dac_nids = alc880_dac_nids,
3700 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3701 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3702 .channel_mode = alc880_threestack_modes,
4e195a7b 3703 .need_dac_fix = 1,
16ded525
TI
3704 .input_mux = &alc880_capture_source,
3705 },
df694daa
KY
3706 [ALC880_TCL_S700] = {
3707 .mixers = { alc880_tcl_s700_mixer },
3708 .init_verbs = { alc880_volume_init_verbs,
3709 alc880_pin_tcl_S700_init_verbs,
3710 alc880_gpio2_init_verbs },
3711 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3712 .dac_nids = alc880_dac_nids,
f9e336f6
TI
3713 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3714 .num_adc_nids = 1, /* single ADC */
df694daa
KY
3715 .hp_nid = 0x03,
3716 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3717 .channel_mode = alc880_2_jack_modes,
3718 .input_mux = &alc880_capture_source,
3719 },
16ded525 3720 [ALC880_5ST] = {
f12ab1e0
TI
3721 .mixers = { alc880_three_stack_mixer,
3722 alc880_five_stack_mixer},
3723 .init_verbs = { alc880_volume_init_verbs,
3724 alc880_pin_5stack_init_verbs },
16ded525
TI
3725 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3726 .dac_nids = alc880_dac_nids,
16ded525
TI
3727 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3728 .channel_mode = alc880_fivestack_modes,
3729 .input_mux = &alc880_capture_source,
3730 },
3731 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3732 .mixers = { alc880_three_stack_mixer,
3733 alc880_five_stack_mixer },
3734 .init_verbs = { alc880_volume_init_verbs,
3735 alc880_pin_5stack_init_verbs },
16ded525
TI
3736 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3737 .dac_nids = alc880_dac_nids,
3738 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3739 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3740 .channel_mode = alc880_fivestack_modes,
3741 .input_mux = &alc880_capture_source,
3742 },
b6482d48
TI
3743 [ALC880_6ST] = {
3744 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3745 .init_verbs = { alc880_volume_init_verbs,
3746 alc880_pin_6stack_init_verbs },
b6482d48
TI
3747 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3748 .dac_nids = alc880_6st_dac_nids,
3749 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3750 .channel_mode = alc880_sixstack_modes,
3751 .input_mux = &alc880_6stack_capture_source,
3752 },
16ded525 3753 [ALC880_6ST_DIG] = {
e9edcee0 3754 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3755 .init_verbs = { alc880_volume_init_verbs,
3756 alc880_pin_6stack_init_verbs },
16ded525
TI
3757 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3758 .dac_nids = alc880_6st_dac_nids,
3759 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3760 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3761 .channel_mode = alc880_sixstack_modes,
3762 .input_mux = &alc880_6stack_capture_source,
3763 },
3764 [ALC880_W810] = {
e9edcee0 3765 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3766 .init_verbs = { alc880_volume_init_verbs,
3767 alc880_pin_w810_init_verbs,
b0af0de5 3768 alc880_gpio2_init_verbs },
16ded525
TI
3769 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3770 .dac_nids = alc880_w810_dac_nids,
3771 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3772 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3773 .channel_mode = alc880_w810_modes,
3774 .input_mux = &alc880_capture_source,
3775 },
3776 [ALC880_Z71V] = {
e9edcee0 3777 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3778 .init_verbs = { alc880_volume_init_verbs,
3779 alc880_pin_z71v_init_verbs },
16ded525
TI
3780 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3781 .dac_nids = alc880_z71v_dac_nids,
3782 .dig_out_nid = ALC880_DIGOUT_NID,
3783 .hp_nid = 0x03,
e9edcee0
TI
3784 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3785 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3786 .input_mux = &alc880_capture_source,
3787 },
3788 [ALC880_F1734] = {
e9edcee0 3789 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3790 .init_verbs = { alc880_volume_init_verbs,
3791 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3792 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3793 .dac_nids = alc880_f1734_dac_nids,
3794 .hp_nid = 0x02,
3795 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3796 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3797 .input_mux = &alc880_f1734_capture_source,
3798 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 3799 .init_hook = alc880_uniwill_p53_init_hook,
16ded525
TI
3800 },
3801 [ALC880_ASUS] = {
e9edcee0 3802 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3803 .init_verbs = { alc880_volume_init_verbs,
3804 alc880_pin_asus_init_verbs,
e9edcee0
TI
3805 alc880_gpio1_init_verbs },
3806 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3807 .dac_nids = alc880_asus_dac_nids,
3808 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3809 .channel_mode = alc880_asus_modes,
4e195a7b 3810 .need_dac_fix = 1,
16ded525
TI
3811 .input_mux = &alc880_capture_source,
3812 },
3813 [ALC880_ASUS_DIG] = {
e9edcee0 3814 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3815 .init_verbs = { alc880_volume_init_verbs,
3816 alc880_pin_asus_init_verbs,
e9edcee0
TI
3817 alc880_gpio1_init_verbs },
3818 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3819 .dac_nids = alc880_asus_dac_nids,
16ded525 3820 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3821 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3822 .channel_mode = alc880_asus_modes,
4e195a7b 3823 .need_dac_fix = 1,
16ded525
TI
3824 .input_mux = &alc880_capture_source,
3825 },
df694daa
KY
3826 [ALC880_ASUS_DIG2] = {
3827 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3828 .init_verbs = { alc880_volume_init_verbs,
3829 alc880_pin_asus_init_verbs,
df694daa
KY
3830 alc880_gpio2_init_verbs }, /* use GPIO2 */
3831 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3832 .dac_nids = alc880_asus_dac_nids,
3833 .dig_out_nid = ALC880_DIGOUT_NID,
3834 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3835 .channel_mode = alc880_asus_modes,
4e195a7b 3836 .need_dac_fix = 1,
df694daa
KY
3837 .input_mux = &alc880_capture_source,
3838 },
16ded525 3839 [ALC880_ASUS_W1V] = {
e9edcee0 3840 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3841 .init_verbs = { alc880_volume_init_verbs,
3842 alc880_pin_asus_init_verbs,
e9edcee0
TI
3843 alc880_gpio1_init_verbs },
3844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3845 .dac_nids = alc880_asus_dac_nids,
16ded525 3846 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3847 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3848 .channel_mode = alc880_asus_modes,
4e195a7b 3849 .need_dac_fix = 1,
16ded525
TI
3850 .input_mux = &alc880_capture_source,
3851 },
3852 [ALC880_UNIWILL_DIG] = {
45bdd1c1 3853 .mixers = { alc880_asus_mixer },
ccc656ce
KY
3854 .init_verbs = { alc880_volume_init_verbs,
3855 alc880_pin_asus_init_verbs },
e9edcee0
TI
3856 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3857 .dac_nids = alc880_asus_dac_nids,
16ded525 3858 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3859 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3860 .channel_mode = alc880_asus_modes,
4e195a7b 3861 .need_dac_fix = 1,
16ded525
TI
3862 .input_mux = &alc880_capture_source,
3863 },
ccc656ce
KY
3864 [ALC880_UNIWILL] = {
3865 .mixers = { alc880_uniwill_mixer },
3866 .init_verbs = { alc880_volume_init_verbs,
3867 alc880_uniwill_init_verbs },
3868 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3869 .dac_nids = alc880_asus_dac_nids,
3870 .dig_out_nid = ALC880_DIGOUT_NID,
3871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3872 .channel_mode = alc880_threestack_modes,
3873 .need_dac_fix = 1,
3874 .input_mux = &alc880_capture_source,
3875 .unsol_event = alc880_uniwill_unsol_event,
a9fd4f3f 3876 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
3877 },
3878 [ALC880_UNIWILL_P53] = {
3879 .mixers = { alc880_uniwill_p53_mixer },
3880 .init_verbs = { alc880_volume_init_verbs,
3881 alc880_uniwill_p53_init_verbs },
3882 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3883 .dac_nids = alc880_asus_dac_nids,
3884 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3885 .channel_mode = alc880_threestack_modes,
3886 .input_mux = &alc880_capture_source,
3887 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 3888 .init_hook = alc880_uniwill_p53_init_hook,
2cf9f0fc
TD
3889 },
3890 [ALC880_FUJITSU] = {
45bdd1c1 3891 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
3892 .init_verbs = { alc880_volume_init_verbs,
3893 alc880_uniwill_p53_init_verbs,
3894 alc880_beep_init_verbs },
3895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3896 .dac_nids = alc880_dac_nids,
d53d7d9e 3897 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3898 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3899 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3900 .input_mux = &alc880_capture_source,
3901 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 3902 .init_hook = alc880_uniwill_p53_init_hook,
ccc656ce 3903 },
df694daa
KY
3904 [ALC880_CLEVO] = {
3905 .mixers = { alc880_three_stack_mixer },
3906 .init_verbs = { alc880_volume_init_verbs,
3907 alc880_pin_clevo_init_verbs },
3908 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3909 .dac_nids = alc880_dac_nids,
3910 .hp_nid = 0x03,
3911 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3912 .channel_mode = alc880_threestack_modes,
4e195a7b 3913 .need_dac_fix = 1,
df694daa
KY
3914 .input_mux = &alc880_capture_source,
3915 },
ae6b813a
TI
3916 [ALC880_LG] = {
3917 .mixers = { alc880_lg_mixer },
3918 .init_verbs = { alc880_volume_init_verbs,
3919 alc880_lg_init_verbs },
3920 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3921 .dac_nids = alc880_lg_dac_nids,
3922 .dig_out_nid = ALC880_DIGOUT_NID,
3923 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3924 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3925 .need_dac_fix = 1,
ae6b813a 3926 .input_mux = &alc880_lg_capture_source,
a9fd4f3f
TI
3927 .unsol_event = alc_automute_amp_unsol_event,
3928 .init_hook = alc880_lg_init_hook,
cb53c626
TI
3929#ifdef CONFIG_SND_HDA_POWER_SAVE
3930 .loopbacks = alc880_lg_loopbacks,
3931#endif
ae6b813a 3932 },
d681518a
TI
3933 [ALC880_LG_LW] = {
3934 .mixers = { alc880_lg_lw_mixer },
3935 .init_verbs = { alc880_volume_init_verbs,
3936 alc880_lg_lw_init_verbs },
0a8c5da3 3937 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3938 .dac_nids = alc880_dac_nids,
3939 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3940 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3941 .channel_mode = alc880_lg_lw_modes,
d681518a 3942 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f
TI
3943 .unsol_event = alc_automute_amp_unsol_event,
3944 .init_hook = alc880_lg_lw_init_hook,
d681518a 3945 },
df99cd33
TI
3946 [ALC880_MEDION_RIM] = {
3947 .mixers = { alc880_medion_rim_mixer },
3948 .init_verbs = { alc880_volume_init_verbs,
3949 alc880_medion_rim_init_verbs,
3950 alc_gpio2_init_verbs },
3951 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3952 .dac_nids = alc880_dac_nids,
3953 .dig_out_nid = ALC880_DIGOUT_NID,
3954 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3955 .channel_mode = alc880_2_jack_modes,
3956 .input_mux = &alc880_medion_rim_capture_source,
3957 .unsol_event = alc880_medion_rim_unsol_event,
a9fd4f3f 3958 .init_hook = alc880_medion_rim_init_hook,
df99cd33 3959 },
16ded525
TI
3960#ifdef CONFIG_SND_DEBUG
3961 [ALC880_TEST] = {
e9edcee0
TI
3962 .mixers = { alc880_test_mixer },
3963 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3964 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3965 .dac_nids = alc880_test_dac_nids,
3966 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3967 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3968 .channel_mode = alc880_test_modes,
3969 .input_mux = &alc880_test_capture_source,
3970 },
3971#endif
3972};
3973
e9edcee0
TI
3974/*
3975 * Automatic parse of I/O pins from the BIOS configuration
3976 */
3977
e9edcee0
TI
3978enum {
3979 ALC_CTL_WIDGET_VOL,
3980 ALC_CTL_WIDGET_MUTE,
3981 ALC_CTL_BIND_MUTE,
3982};
c8b6bf9b 3983static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3984 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3985 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3986 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3987};
3988
3989/* add dynamic controls */
f12ab1e0
TI
3990static int add_control(struct alc_spec *spec, int type, const char *name,
3991 unsigned long val)
e9edcee0 3992{
c8b6bf9b 3993 struct snd_kcontrol_new *knew;
e9edcee0 3994
603c4019
TI
3995 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3996 knew = snd_array_new(&spec->kctls);
3997 if (!knew)
3998 return -ENOMEM;
e9edcee0 3999 *knew = alc880_control_templates[type];
543537bd 4000 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4001 if (!knew->name)
e9edcee0
TI
4002 return -ENOMEM;
4003 knew->private_value = val;
e9edcee0
TI
4004 return 0;
4005}
4006
4007#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4008#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4009#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4010#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4011#define alc880_is_input_pin(nid) ((nid) >= 0x18)
4012#define alc880_input_pin_idx(nid) ((nid) - 0x18)
4013#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4014#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4015#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4016#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4017#define ALC880_PIN_CD_NID 0x1c
4018
4019/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4020static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4021 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4022{
4023 hda_nid_t nid;
4024 int assigned[4];
4025 int i, j;
4026
4027 memset(assigned, 0, sizeof(assigned));
b0af0de5 4028 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4029
4030 /* check the pins hardwired to audio widget */
4031 for (i = 0; i < cfg->line_outs; i++) {
4032 nid = cfg->line_out_pins[i];
4033 if (alc880_is_fixed_pin(nid)) {
4034 int idx = alc880_fixed_pin_idx(nid);
5014f193 4035 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4036 assigned[idx] = 1;
4037 }
4038 }
4039 /* left pins can be connect to any audio widget */
4040 for (i = 0; i < cfg->line_outs; i++) {
4041 nid = cfg->line_out_pins[i];
4042 if (alc880_is_fixed_pin(nid))
4043 continue;
4044 /* search for an empty channel */
4045 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4046 if (!assigned[j]) {
4047 spec->multiout.dac_nids[i] =
4048 alc880_idx_to_dac(j);
e9edcee0
TI
4049 assigned[j] = 1;
4050 break;
4051 }
4052 }
4053 }
4054 spec->multiout.num_dacs = cfg->line_outs;
4055 return 0;
4056}
4057
4058/* add playback controls from the parsed DAC table */
df694daa
KY
4059static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4060 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4061{
4062 char name[32];
f12ab1e0
TI
4063 static const char *chname[4] = {
4064 "Front", "Surround", NULL /*CLFE*/, "Side"
4065 };
e9edcee0
TI
4066 hda_nid_t nid;
4067 int i, err;
4068
4069 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4070 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4071 continue;
4072 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4073 if (i == 2) {
4074 /* Center/LFE */
f12ab1e0
TI
4075 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4076 "Center Playback Volume",
4077 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4078 HDA_OUTPUT));
4079 if (err < 0)
e9edcee0 4080 return err;
f12ab1e0
TI
4081 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4082 "LFE Playback Volume",
4083 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4084 HDA_OUTPUT));
4085 if (err < 0)
e9edcee0 4086 return err;
f12ab1e0
TI
4087 err = add_control(spec, ALC_CTL_BIND_MUTE,
4088 "Center Playback Switch",
4089 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4090 HDA_INPUT));
4091 if (err < 0)
e9edcee0 4092 return err;
f12ab1e0
TI
4093 err = add_control(spec, ALC_CTL_BIND_MUTE,
4094 "LFE Playback Switch",
4095 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4096 HDA_INPUT));
4097 if (err < 0)
e9edcee0
TI
4098 return err;
4099 } else {
4100 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
4101 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4102 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4103 HDA_OUTPUT));
4104 if (err < 0)
e9edcee0
TI
4105 return err;
4106 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
4107 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4108 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4109 HDA_INPUT));
4110 if (err < 0)
e9edcee0
TI
4111 return err;
4112 }
4113 }
e9edcee0
TI
4114 return 0;
4115}
4116
8d88bc3d
TI
4117/* add playback controls for speaker and HP outputs */
4118static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4119 const char *pfx)
e9edcee0
TI
4120{
4121 hda_nid_t nid;
4122 int err;
8d88bc3d 4123 char name[32];
e9edcee0 4124
f12ab1e0 4125 if (!pin)
e9edcee0
TI
4126 return 0;
4127
4128 if (alc880_is_fixed_pin(pin)) {
4129 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4130 /* specify the DAC as the extra output */
f12ab1e0 4131 if (!spec->multiout.hp_nid)
e9edcee0 4132 spec->multiout.hp_nid = nid;
82bc955f
TI
4133 else
4134 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4135 /* control HP volume/switch on the output mixer amp */
4136 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 4137 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4138 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4139 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4140 if (err < 0)
e9edcee0 4141 return err;
8d88bc3d 4142 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4143 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4144 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4145 if (err < 0)
e9edcee0
TI
4146 return err;
4147 } else if (alc880_is_multi_pin(pin)) {
4148 /* set manual connection */
e9edcee0 4149 /* we have only a switch on HP-out PIN */
8d88bc3d 4150 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4151 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4152 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4153 if (err < 0)
e9edcee0
TI
4154 return err;
4155 }
4156 return 0;
4157}
4158
4159/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4160static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4161 const char *ctlname,
df694daa 4162 int idx, hda_nid_t mix_nid)
e9edcee0
TI
4163{
4164 char name[32];
df694daa 4165 int err;
e9edcee0
TI
4166
4167 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
4168 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4169 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4170 if (err < 0)
e9edcee0
TI
4171 return err;
4172 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
4173 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4174 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4175 if (err < 0)
e9edcee0
TI
4176 return err;
4177 return 0;
4178}
4179
4180/* create playback/capture controls for input pins */
df694daa
KY
4181static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4182 const struct auto_pin_cfg *cfg)
e9edcee0 4183{
61b9b9b1 4184 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4185 int i, err, idx;
e9edcee0
TI
4186
4187 for (i = 0; i < AUTO_PIN_LAST; i++) {
4188 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 4189 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
4190 err = new_analog_input(spec, cfg->input_pins[i],
4191 auto_pin_cfg_labels[i],
df694daa 4192 idx, 0x0b);
e9edcee0
TI
4193 if (err < 0)
4194 return err;
f12ab1e0
TI
4195 imux->items[imux->num_items].label =
4196 auto_pin_cfg_labels[i];
4197 imux->items[imux->num_items].index =
4198 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
4199 imux->num_items++;
4200 }
4201 }
4202 return 0;
4203}
4204
f6c7e546
TI
4205static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4206 unsigned int pin_type)
4207{
4208 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4209 pin_type);
4210 /* unmute pin */
d260cdf6
TI
4211 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4212 AMP_OUT_UNMUTE);
f6c7e546
TI
4213}
4214
df694daa
KY
4215static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4216 hda_nid_t nid, int pin_type,
e9edcee0
TI
4217 int dac_idx)
4218{
f6c7e546 4219 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4220 /* need the manual connection? */
4221 if (alc880_is_multi_pin(nid)) {
4222 struct alc_spec *spec = codec->spec;
4223 int idx = alc880_multi_pin_idx(nid);
4224 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4225 AC_VERB_SET_CONNECT_SEL,
4226 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4227 }
4228}
4229
baba8ee9
TI
4230static int get_pin_type(int line_out_type)
4231{
4232 if (line_out_type == AUTO_PIN_HP_OUT)
4233 return PIN_HP;
4234 else
4235 return PIN_OUT;
4236}
4237
e9edcee0
TI
4238static void alc880_auto_init_multi_out(struct hda_codec *codec)
4239{
4240 struct alc_spec *spec = codec->spec;
4241 int i;
ea1fb29a 4242
e9edcee0
TI
4243 for (i = 0; i < spec->autocfg.line_outs; i++) {
4244 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4245 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4246 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4247 }
4248}
4249
8d88bc3d 4250static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4251{
4252 struct alc_spec *spec = codec->spec;
4253 hda_nid_t pin;
4254
82bc955f 4255 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4256 if (pin) /* connect to front */
4257 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4258 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4259 if (pin) /* connect to front */
4260 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4261}
4262
4263static void alc880_auto_init_analog_input(struct hda_codec *codec)
4264{
4265 struct alc_spec *spec = codec->spec;
4266 int i;
4267
4268 for (i = 0; i < AUTO_PIN_LAST; i++) {
4269 hda_nid_t nid = spec->autocfg.input_pins[i];
4270 if (alc880_is_input_pin(nid)) {
23f0c048 4271 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4272 if (nid != ALC880_PIN_CD_NID &&
4273 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4274 snd_hda_codec_write(codec, nid, 0,
4275 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4276 AMP_OUT_MUTE);
4277 }
4278 }
4279}
4280
4281/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4282/* return 1 if successful, 0 if the proper config is not found,
4283 * or a negative error code
4284 */
e9edcee0
TI
4285static int alc880_parse_auto_config(struct hda_codec *codec)
4286{
4287 struct alc_spec *spec = codec->spec;
6a05ac4a 4288 int i, err;
df694daa 4289 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4290
f12ab1e0
TI
4291 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4292 alc880_ignore);
4293 if (err < 0)
e9edcee0 4294 return err;
f12ab1e0 4295 if (!spec->autocfg.line_outs)
e9edcee0 4296 return 0; /* can't find valid BIOS pin config */
df694daa 4297
f12ab1e0
TI
4298 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4299 if (err < 0)
4300 return err;
4301 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4302 if (err < 0)
4303 return err;
4304 err = alc880_auto_create_extra_out(spec,
4305 spec->autocfg.speaker_pins[0],
4306 "Speaker");
4307 if (err < 0)
4308 return err;
4309 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4310 "Headphone");
4311 if (err < 0)
4312 return err;
4313 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4314 if (err < 0)
e9edcee0
TI
4315 return err;
4316
4317 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4318
6a05ac4a
TI
4319 /* check multiple SPDIF-out (for recent codecs) */
4320 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4321 hda_nid_t dig_nid;
4322 err = snd_hda_get_connections(codec,
4323 spec->autocfg.dig_out_pins[i],
4324 &dig_nid, 1);
4325 if (err < 0)
4326 continue;
4327 if (!i)
4328 spec->multiout.dig_out_nid = dig_nid;
4329 else {
4330 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4331 spec->slave_dig_outs[i - 1] = dig_nid;
4332 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4333 break;
4334 }
4335 }
e9edcee0
TI
4336 if (spec->autocfg.dig_in_pin)
4337 spec->dig_in_nid = ALC880_DIGIN_NID;
4338
603c4019 4339 if (spec->kctls.list)
d88897ea 4340 add_mixer(spec, spec->kctls.list);
e9edcee0 4341
d88897ea 4342 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4343
a1e8d2da 4344 spec->num_mux_defs = 1;
61b9b9b1 4345 spec->input_mux = &spec->private_imux[0];
e9edcee0 4346
4a79ba34
TI
4347 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4348
e9edcee0
TI
4349 return 1;
4350}
4351
ae6b813a
TI
4352/* additional initialization for auto-configuration model */
4353static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4354{
f6c7e546 4355 struct alc_spec *spec = codec->spec;
e9edcee0 4356 alc880_auto_init_multi_out(codec);
8d88bc3d 4357 alc880_auto_init_extra_out(codec);
e9edcee0 4358 alc880_auto_init_analog_input(codec);
f6c7e546 4359 if (spec->unsol_event)
7fb0d78f 4360 alc_inithook(codec);
e9edcee0
TI
4361}
4362
f9e336f6
TI
4363static void set_capture_mixer(struct alc_spec *spec)
4364{
a23b688f
TI
4365 static struct snd_kcontrol_new *caps[2][3] = {
4366 { alc_capture_mixer_nosrc1,
4367 alc_capture_mixer_nosrc2,
4368 alc_capture_mixer_nosrc3 },
4369 { alc_capture_mixer1,
4370 alc_capture_mixer2,
4371 alc_capture_mixer3 },
f9e336f6 4372 };
a23b688f
TI
4373 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4374 int mux;
4375 if (spec->input_mux && spec->input_mux->num_items > 1)
4376 mux = 1;
4377 else
4378 mux = 0;
4379 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4380 }
f9e336f6
TI
4381}
4382
45bdd1c1
TI
4383#define set_beep_amp(spec, nid, idx, dir) \
4384 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4385
4386/*
4387 * OK, here we have finally the patch for ALC880
4388 */
4389
1da177e4
LT
4390static int patch_alc880(struct hda_codec *codec)
4391{
4392 struct alc_spec *spec;
4393 int board_config;
df694daa 4394 int err;
1da177e4 4395
e560d8d8 4396 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4397 if (spec == NULL)
4398 return -ENOMEM;
4399
4400 codec->spec = spec;
4401
f5fcc13c
TI
4402 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4403 alc880_models,
4404 alc880_cfg_tbl);
4405 if (board_config < 0) {
9c7f852e
TI
4406 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4407 "trying auto-probe from BIOS...\n");
e9edcee0 4408 board_config = ALC880_AUTO;
1da177e4 4409 }
1da177e4 4410
e9edcee0
TI
4411 if (board_config == ALC880_AUTO) {
4412 /* automatic parse from the BIOS config */
4413 err = alc880_parse_auto_config(codec);
4414 if (err < 0) {
4415 alc_free(codec);
4416 return err;
f12ab1e0 4417 } else if (!err) {
9c7f852e
TI
4418 printk(KERN_INFO
4419 "hda_codec: Cannot set up configuration "
4420 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
4421 board_config = ALC880_3ST;
4422 }
1da177e4
LT
4423 }
4424
680cd536
KK
4425 err = snd_hda_attach_beep_device(codec, 0x1);
4426 if (err < 0) {
4427 alc_free(codec);
4428 return err;
4429 }
4430
df694daa
KY
4431 if (board_config != ALC880_AUTO)
4432 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
4433
4434 spec->stream_name_analog = "ALC880 Analog";
4435 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4436 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 4437 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
4438
4439 spec->stream_name_digital = "ALC880 Digital";
4440 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4441 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4442
f12ab1e0 4443 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 4444 /* check whether NID 0x07 is valid */
54d17403 4445 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
4446 /* get type */
4447 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
4448 if (wcap != AC_WID_AUD_IN) {
4449 spec->adc_nids = alc880_adc_nids_alt;
4450 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
4451 } else {
4452 spec->adc_nids = alc880_adc_nids;
4453 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
4454 }
4455 }
f9e336f6 4456 set_capture_mixer(spec);
45bdd1c1 4457 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 4458
2134ea4f
TI
4459 spec->vmaster_nid = 0x0c;
4460
1da177e4 4461 codec->patch_ops = alc_patch_ops;
e9edcee0 4462 if (board_config == ALC880_AUTO)
ae6b813a 4463 spec->init_hook = alc880_auto_init;
cb53c626
TI
4464#ifdef CONFIG_SND_HDA_POWER_SAVE
4465 if (!spec->loopback.amplist)
4466 spec->loopback.amplist = alc880_loopbacks;
4467#endif
daead538 4468 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
4469
4470 return 0;
4471}
4472
e9edcee0 4473
1da177e4
LT
4474/*
4475 * ALC260 support
4476 */
4477
e9edcee0
TI
4478static hda_nid_t alc260_dac_nids[1] = {
4479 /* front */
4480 0x02,
4481};
4482
4483static hda_nid_t alc260_adc_nids[1] = {
4484 /* ADC0 */
4485 0x04,
4486};
4487
df694daa 4488static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4489 /* ADC1 */
4490 0x05,
4491};
4492
d57fdac0
JW
4493/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4494 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4495 */
4496static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4497 /* ADC0, ADC1 */
4498 0x04, 0x05
4499};
4500
e9edcee0
TI
4501#define ALC260_DIGOUT_NID 0x03
4502#define ALC260_DIGIN_NID 0x06
4503
4504static struct hda_input_mux alc260_capture_source = {
4505 .num_items = 4,
4506 .items = {
4507 { "Mic", 0x0 },
4508 { "Front Mic", 0x1 },
4509 { "Line", 0x2 },
4510 { "CD", 0x4 },
4511 },
4512};
4513
17e7aec6 4514/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4515 * headphone jack and the internal CD lines since these are the only pins at
4516 * which audio can appear. For flexibility, also allow the option of
4517 * recording the mixer output on the second ADC (ADC0 doesn't have a
4518 * connection to the mixer output).
a9430dd8 4519 */
a1e8d2da
JW
4520static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4521 {
4522 .num_items = 3,
4523 .items = {
4524 { "Mic/Line", 0x0 },
4525 { "CD", 0x4 },
4526 { "Headphone", 0x2 },
4527 },
a9430dd8 4528 },
a1e8d2da
JW
4529 {
4530 .num_items = 4,
4531 .items = {
4532 { "Mic/Line", 0x0 },
4533 { "CD", 0x4 },
4534 { "Headphone", 0x2 },
4535 { "Mixer", 0x5 },
4536 },
4537 },
4538
a9430dd8
JW
4539};
4540
a1e8d2da
JW
4541/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4542 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4543 */
a1e8d2da
JW
4544static struct hda_input_mux alc260_acer_capture_sources[2] = {
4545 {
4546 .num_items = 4,
4547 .items = {
4548 { "Mic", 0x0 },
4549 { "Line", 0x2 },
4550 { "CD", 0x4 },
4551 { "Headphone", 0x5 },
4552 },
4553 },
4554 {
4555 .num_items = 5,
4556 .items = {
4557 { "Mic", 0x0 },
4558 { "Line", 0x2 },
4559 { "CD", 0x4 },
4560 { "Headphone", 0x6 },
4561 { "Mixer", 0x5 },
4562 },
0bfc90e9
JW
4563 },
4564};
cc959489
MS
4565
4566/* Maxdata Favorit 100XS */
4567static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4568 {
4569 .num_items = 2,
4570 .items = {
4571 { "Line/Mic", 0x0 },
4572 { "CD", 0x4 },
4573 },
4574 },
4575 {
4576 .num_items = 3,
4577 .items = {
4578 { "Line/Mic", 0x0 },
4579 { "CD", 0x4 },
4580 { "Mixer", 0x5 },
4581 },
4582 },
4583};
4584
1da177e4
LT
4585/*
4586 * This is just place-holder, so there's something for alc_build_pcms to look
4587 * at when it calculates the maximum number of channels. ALC260 has no mixer
4588 * element which allows changing the channel mode, so the verb list is
4589 * never used.
4590 */
d2a6d7dc 4591static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4592 { 2, NULL },
4593};
4594
df694daa
KY
4595
4596/* Mixer combinations
4597 *
4598 * basic: base_output + input + pc_beep + capture
4599 * HP: base_output + input + capture_alt
4600 * HP_3013: hp_3013 + input + capture
4601 * fujitsu: fujitsu + capture
0bfc90e9 4602 * acer: acer + capture
df694daa
KY
4603 */
4604
4605static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4606 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4607 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4608 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4609 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4610 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4611 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4612 { } /* end */
f12ab1e0 4613};
1da177e4 4614
df694daa 4615static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4616 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4617 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4618 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4619 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4621 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4622 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4623 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4624 { } /* end */
4625};
4626
bec15c3a
TI
4627/* update HP, line and mono out pins according to the master switch */
4628static void alc260_hp_master_update(struct hda_codec *codec,
4629 hda_nid_t hp, hda_nid_t line,
4630 hda_nid_t mono)
4631{
4632 struct alc_spec *spec = codec->spec;
4633 unsigned int val = spec->master_sw ? PIN_HP : 0;
4634 /* change HP and line-out pins */
30cde0aa 4635 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 4636 val);
30cde0aa 4637 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4638 val);
4639 /* mono (speaker) depending on the HP jack sense */
4640 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 4641 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4642 val);
4643}
4644
4645static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4646 struct snd_ctl_elem_value *ucontrol)
4647{
4648 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4649 struct alc_spec *spec = codec->spec;
4650 *ucontrol->value.integer.value = spec->master_sw;
4651 return 0;
4652}
4653
4654static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4655 struct snd_ctl_elem_value *ucontrol)
4656{
4657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4658 struct alc_spec *spec = codec->spec;
4659 int val = !!*ucontrol->value.integer.value;
4660 hda_nid_t hp, line, mono;
4661
4662 if (val == spec->master_sw)
4663 return 0;
4664 spec->master_sw = val;
4665 hp = (kcontrol->private_value >> 16) & 0xff;
4666 line = (kcontrol->private_value >> 8) & 0xff;
4667 mono = kcontrol->private_value & 0xff;
4668 alc260_hp_master_update(codec, hp, line, mono);
4669 return 1;
4670}
4671
4672static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4673 {
4674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4675 .name = "Master Playback Switch",
4676 .info = snd_ctl_boolean_mono_info,
4677 .get = alc260_hp_master_sw_get,
4678 .put = alc260_hp_master_sw_put,
4679 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4680 },
4681 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4682 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4684 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4686 HDA_OUTPUT),
4687 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4688 { } /* end */
4689};
4690
4691static struct hda_verb alc260_hp_unsol_verbs[] = {
4692 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4693 {},
4694};
4695
4696static void alc260_hp_automute(struct hda_codec *codec)
4697{
4698 struct alc_spec *spec = codec->spec;
4699 unsigned int present;
4700
4701 present = snd_hda_codec_read(codec, 0x10, 0,
4702 AC_VERB_GET_PIN_SENSE, 0);
4703 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4704 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4705}
4706
4707static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4708{
4709 if ((res >> 26) == ALC880_HP_EVENT)
4710 alc260_hp_automute(codec);
4711}
4712
df694daa 4713static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4714 {
4715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4716 .name = "Master Playback Switch",
4717 .info = snd_ctl_boolean_mono_info,
4718 .get = alc260_hp_master_sw_get,
4719 .put = alc260_hp_master_sw_put,
30cde0aa 4720 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 4721 },
df694daa
KY
4722 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4723 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4724 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4725 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4726 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4728 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4729 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4730 { } /* end */
4731};
4732
3f878308
KY
4733static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4734 .ops = &snd_hda_bind_vol,
4735 .values = {
4736 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4737 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4738 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4739 0
4740 },
4741};
4742
4743static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4744 .ops = &snd_hda_bind_sw,
4745 .values = {
4746 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4747 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4748 0
4749 },
4750};
4751
4752static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4753 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4754 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4755 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4756 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4757 { } /* end */
4758};
4759
bec15c3a
TI
4760static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4761 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4762 {},
4763};
4764
4765static void alc260_hp_3013_automute(struct hda_codec *codec)
4766{
4767 struct alc_spec *spec = codec->spec;
4768 unsigned int present;
4769
4770 present = snd_hda_codec_read(codec, 0x15, 0,
4771 AC_VERB_GET_PIN_SENSE, 0);
4772 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
30cde0aa 4773 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
4774}
4775
4776static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4777 unsigned int res)
4778{
4779 if ((res >> 26) == ALC880_HP_EVENT)
4780 alc260_hp_3013_automute(codec);
4781}
4782
3f878308
KY
4783static void alc260_hp_3012_automute(struct hda_codec *codec)
4784{
4785 unsigned int present, bits;
4786
4787 present = snd_hda_codec_read(codec, 0x10, 0,
4788 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4789
4790 bits = present ? 0 : PIN_OUT;
4791 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4792 bits);
4793 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4794 bits);
4795 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4796 bits);
4797}
4798
4799static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4800 unsigned int res)
4801{
4802 if ((res >> 26) == ALC880_HP_EVENT)
4803 alc260_hp_3012_automute(codec);
4804}
4805
4806/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4807 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4808 */
c8b6bf9b 4809static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4811 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4812 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4813 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4814 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4815 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4816 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4817 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
4818 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4819 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4820 { } /* end */
4821};
4822
a1e8d2da
JW
4823/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4824 * versions of the ALC260 don't act on requests to enable mic bias from NID
4825 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4826 * datasheet doesn't mention this restriction. At this stage it's not clear
4827 * whether this behaviour is intentional or is a hardware bug in chip
4828 * revisions available in early 2006. Therefore for now allow the
4829 * "Headphone Jack Mode" control to span all choices, but if it turns out
4830 * that the lack of mic bias for this NID is intentional we could change the
4831 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4832 *
4833 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4834 * don't appear to make the mic bias available from the "line" jack, even
4835 * though the NID used for this jack (0x14) can supply it. The theory is
4836 * that perhaps Acer have included blocking capacitors between the ALC260
4837 * and the output jack. If this turns out to be the case for all such
4838 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4839 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4840 *
4841 * The C20x Tablet series have a mono internal speaker which is controlled
4842 * via the chip's Mono sum widget and pin complex, so include the necessary
4843 * controls for such models. On models without a "mono speaker" the control
4844 * won't do anything.
a1e8d2da 4845 */
0bfc90e9
JW
4846static struct snd_kcontrol_new alc260_acer_mixer[] = {
4847 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4848 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4849 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4850 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4851 HDA_OUTPUT),
31bffaa9 4852 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4853 HDA_INPUT),
0bfc90e9
JW
4854 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4855 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4857 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4858 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4859 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4860 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4861 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
4862 { } /* end */
4863};
4864
cc959489
MS
4865/* Maxdata Favorit 100XS: one output and one input (0x12) jack
4866 */
4867static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4868 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4869 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4870 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4871 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4872 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4873 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4874 { } /* end */
4875};
4876
bc9f98a9
KY
4877/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4878 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4879 */
4880static struct snd_kcontrol_new alc260_will_mixer[] = {
4881 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4882 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4884 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4885 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4886 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4887 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4888 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4889 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4890 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
4891 { } /* end */
4892};
4893
4894/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4895 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4896 */
4897static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4898 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4899 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4901 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4902 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4903 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4904 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4905 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4906 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4907 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4908 { } /* end */
4909};
4910
df694daa
KY
4911/*
4912 * initialization verbs
4913 */
1da177e4
LT
4914static struct hda_verb alc260_init_verbs[] = {
4915 /* Line In pin widget for input */
05acb863 4916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4917 /* CD pin widget for input */
05acb863 4918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4919 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4920 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4921 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4922 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4923 /* LINE-2 is used for line-out in rear */
05acb863 4924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4925 /* select line-out */
fd56f2db 4926 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4927 /* LINE-OUT pin */
05acb863 4928 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4929 /* enable HP */
05acb863 4930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4931 /* enable Mono */
05acb863
TI
4932 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4933 /* mute capture amp left and right */
16ded525 4934 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4935 /* set connection select to line in (default select for this ADC) */
4936 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4937 /* mute capture amp left and right */
4938 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4939 /* set connection select to line in (default select for this ADC) */
4940 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4941 /* set vol=0 Line-Out mixer amp left and right */
4942 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4943 /* unmute pin widget amp left and right (no gain on this amp) */
4944 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4945 /* set vol=0 HP mixer amp left and right */
4946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4947 /* unmute pin widget amp left and right (no gain on this amp) */
4948 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4949 /* set vol=0 Mono mixer amp left and right */
4950 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4951 /* unmute pin widget amp left and right (no gain on this amp) */
4952 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4953 /* unmute LINE-2 out pin */
4954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4955 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4956 * Line In 2 = 0x03
4957 */
cb53c626
TI
4958 /* mute analog inputs */
4959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4964 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4965 /* mute Front out path */
4966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4968 /* mute Headphone out path */
4969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4971 /* mute Mono out path */
4972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4974 { }
4975};
4976
474167d6 4977#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4978static struct hda_verb alc260_hp_init_verbs[] = {
4979 /* Headphone and output */
4980 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4981 /* mono output */
4982 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4983 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4985 /* Mic2 (front panel) pin widget for input and vref at 80% */
4986 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4987 /* Line In pin widget for input */
4988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4989 /* Line-2 pin widget for output */
4990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4991 /* CD pin widget for input */
4992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4993 /* unmute amp left and right */
4994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4995 /* set connection select to line in (default select for this ADC) */
4996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4997 /* unmute Line-Out mixer amp left and right (volume = 0) */
4998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4999 /* mute pin widget amp left and right (no gain on this amp) */
5000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5001 /* unmute HP mixer amp left and right (volume = 0) */
5002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5003 /* mute pin widget amp left and right (no gain on this amp) */
5004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5005 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5006 * Line In 2 = 0x03
5007 */
cb53c626
TI
5008 /* mute analog inputs */
5009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5014 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5015 /* Unmute Front out path */
5016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5018 /* Unmute Headphone out path */
5019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5021 /* Unmute Mono out path */
5022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5024 { }
5025};
474167d6 5026#endif
df694daa
KY
5027
5028static struct hda_verb alc260_hp_3013_init_verbs[] = {
5029 /* Line out and output */
5030 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5031 /* mono output */
5032 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5033 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5034 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5035 /* Mic2 (front panel) pin widget for input and vref at 80% */
5036 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5037 /* Line In pin widget for input */
5038 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5039 /* Headphone pin widget for output */
5040 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5041 /* CD pin widget for input */
5042 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5043 /* unmute amp left and right */
5044 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5045 /* set connection select to line in (default select for this ADC) */
5046 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5047 /* unmute Line-Out mixer amp left and right (volume = 0) */
5048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5049 /* mute pin widget amp left and right (no gain on this amp) */
5050 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5051 /* unmute HP mixer amp left and right (volume = 0) */
5052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5053 /* mute pin widget amp left and right (no gain on this amp) */
5054 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5055 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5056 * Line In 2 = 0x03
5057 */
cb53c626
TI
5058 /* mute analog inputs */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5064 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5065 /* Unmute Front out path */
5066 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5068 /* Unmute Headphone out path */
5069 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5071 /* Unmute Mono out path */
5072 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5074 { }
5075};
5076
a9430dd8 5077/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5078 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5079 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5080 */
5081static struct hda_verb alc260_fujitsu_init_verbs[] = {
5082 /* Disable all GPIOs */
5083 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5084 /* Internal speaker is connected to headphone pin */
5085 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5086 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5087 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5088 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5089 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5090 /* Ensure all other unused pins are disabled and muted. */
5091 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5093 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5094 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5095 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5096 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5099
5100 /* Disable digital (SPDIF) pins */
5101 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5102 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5103
ea1fb29a 5104 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5105 * when acting as an output.
5106 */
5107 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5108
f7ace40d 5109 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5110 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5111 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5112 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5116 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5118 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5119
f7ace40d
JW
5120 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5121 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5122 /* Unmute Line1 pin widget output buffer since it starts as an output.
5123 * If the pin mode is changed by the user the pin mode control will
5124 * take care of enabling the pin's input/output buffers as needed.
5125 * Therefore there's no need to enable the input buffer at this
5126 * stage.
cdcd9268 5127 */
f7ace40d 5128 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5129 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5130 * mixer ctrl)
5131 */
f7ace40d
JW
5132 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5133
5134 /* Mute capture amp left and right */
5135 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5136 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5137 * in (on mic1 pin)
5138 */
5139 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5140
5141 /* Do the same for the second ADC: mute capture input amp and
5142 * set ADC connection to line in (on mic1 pin)
5143 */
5144 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5145 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5146
5147 /* Mute all inputs to mixer widget (even unconnected ones) */
5148 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5156
5157 { }
a9430dd8
JW
5158};
5159
0bfc90e9
JW
5160/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5161 * similar laptops (adapted from Fujitsu init verbs).
5162 */
5163static struct hda_verb alc260_acer_init_verbs[] = {
5164 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5165 * the headphone jack. Turn this on and rely on the standard mute
5166 * methods whenever the user wants to turn these outputs off.
5167 */
5168 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5169 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5170 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5171 /* Internal speaker/Headphone jack is connected to Line-out pin */
5172 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5173 /* Internal microphone/Mic jack is connected to Mic1 pin */
5174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5175 /* Line In jack is connected to Line1 pin */
5176 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5177 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5178 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5179 /* Ensure all other unused pins are disabled and muted. */
5180 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5181 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5182 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5183 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5184 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5185 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5186 /* Disable digital (SPDIF) pins */
5187 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5188 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5189
ea1fb29a 5190 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5191 * bus when acting as outputs.
5192 */
5193 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5194 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5195
5196 /* Start with output sum widgets muted and their output gains at min */
5197 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5203 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5204 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5205 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5206
f12ab1e0
TI
5207 /* Unmute Line-out pin widget amp left and right
5208 * (no equiv mixer ctrl)
5209 */
0bfc90e9 5210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5211 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5212 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5213 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5214 * inputs. If the pin mode is changed by the user the pin mode control
5215 * will take care of enabling the pin's input/output buffers as needed.
5216 * Therefore there's no need to enable the input buffer at this
5217 * stage.
5218 */
5219 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5221
5222 /* Mute capture amp left and right */
5223 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5224 /* Set ADC connection select to match default mixer setting - mic
5225 * (on mic1 pin)
5226 */
5227 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5228
5229 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5230 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5231 */
5232 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5233 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5234
5235 /* Mute all inputs to mixer widget (even unconnected ones) */
5236 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5238 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5239 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5243 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5244
5245 { }
5246};
5247
cc959489
MS
5248/* Initialisation sequence for Maxdata Favorit 100XS
5249 * (adapted from Acer init verbs).
5250 */
5251static struct hda_verb alc260_favorit100_init_verbs[] = {
5252 /* GPIO 0 enables the output jack.
5253 * Turn this on and rely on the standard mute
5254 * methods whenever the user wants to turn these outputs off.
5255 */
5256 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5257 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5258 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5259 /* Line/Mic input jack is connected to Mic1 pin */
5260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5261 /* Ensure all other unused pins are disabled and muted. */
5262 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5263 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5264 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5265 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5266 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5267 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272 /* Disable digital (SPDIF) pins */
5273 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5274 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5275
5276 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5277 * bus when acting as outputs.
5278 */
5279 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5280 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5281
5282 /* Start with output sum widgets muted and their output gains at min */
5283 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5284 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5289 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5290 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5291 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5292
5293 /* Unmute Line-out pin widget amp left and right
5294 * (no equiv mixer ctrl)
5295 */
5296 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5297 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5298 * inputs. If the pin mode is changed by the user the pin mode control
5299 * will take care of enabling the pin's input/output buffers as needed.
5300 * Therefore there's no need to enable the input buffer at this
5301 * stage.
5302 */
5303 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5304
5305 /* Mute capture amp left and right */
5306 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5307 /* Set ADC connection select to match default mixer setting - mic
5308 * (on mic1 pin)
5309 */
5310 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5311
5312 /* Do similar with the second ADC: mute capture input amp and
5313 * set ADC connection to mic to match ALSA's default state.
5314 */
5315 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5316 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5317
5318 /* Mute all inputs to mixer widget (even unconnected ones) */
5319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5327
5328 { }
5329};
5330
bc9f98a9
KY
5331static struct hda_verb alc260_will_verbs[] = {
5332 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5333 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5334 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5335 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5336 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5337 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5338 {}
5339};
5340
5341static struct hda_verb alc260_replacer_672v_verbs[] = {
5342 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5343 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5344 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5345
5346 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5347 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5348 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5349
5350 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5351 {}
5352};
5353
5354/* toggle speaker-output according to the hp-jack state */
5355static void alc260_replacer_672v_automute(struct hda_codec *codec)
5356{
5357 unsigned int present;
5358
5359 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5360 present = snd_hda_codec_read(codec, 0x0f, 0,
5361 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5362 if (present) {
82beb8fd
TI
5363 snd_hda_codec_write_cache(codec, 0x01, 0,
5364 AC_VERB_SET_GPIO_DATA, 1);
5365 snd_hda_codec_write_cache(codec, 0x0f, 0,
5366 AC_VERB_SET_PIN_WIDGET_CONTROL,
5367 PIN_HP);
bc9f98a9 5368 } else {
82beb8fd
TI
5369 snd_hda_codec_write_cache(codec, 0x01, 0,
5370 AC_VERB_SET_GPIO_DATA, 0);
5371 snd_hda_codec_write_cache(codec, 0x0f, 0,
5372 AC_VERB_SET_PIN_WIDGET_CONTROL,
5373 PIN_OUT);
bc9f98a9
KY
5374 }
5375}
5376
5377static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5378 unsigned int res)
5379{
5380 if ((res >> 26) == ALC880_HP_EVENT)
5381 alc260_replacer_672v_automute(codec);
5382}
5383
3f878308
KY
5384static struct hda_verb alc260_hp_dc7600_verbs[] = {
5385 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5386 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5387 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5388 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5389 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5391 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5392 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5393 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5394 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5395 {}
5396};
5397
7cf51e48
JW
5398/* Test configuration for debugging, modelled after the ALC880 test
5399 * configuration.
5400 */
5401#ifdef CONFIG_SND_DEBUG
5402static hda_nid_t alc260_test_dac_nids[1] = {
5403 0x02,
5404};
5405static hda_nid_t alc260_test_adc_nids[2] = {
5406 0x04, 0x05,
5407};
a1e8d2da 5408/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 5409 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 5410 * is NID 0x04.
17e7aec6 5411 */
a1e8d2da
JW
5412static struct hda_input_mux alc260_test_capture_sources[2] = {
5413 {
5414 .num_items = 7,
5415 .items = {
5416 { "MIC1 pin", 0x0 },
5417 { "MIC2 pin", 0x1 },
5418 { "LINE1 pin", 0x2 },
5419 { "LINE2 pin", 0x3 },
5420 { "CD pin", 0x4 },
5421 { "LINE-OUT pin", 0x5 },
5422 { "HP-OUT pin", 0x6 },
5423 },
5424 },
5425 {
5426 .num_items = 8,
5427 .items = {
5428 { "MIC1 pin", 0x0 },
5429 { "MIC2 pin", 0x1 },
5430 { "LINE1 pin", 0x2 },
5431 { "LINE2 pin", 0x3 },
5432 { "CD pin", 0x4 },
5433 { "Mixer", 0x5 },
5434 { "LINE-OUT pin", 0x6 },
5435 { "HP-OUT pin", 0x7 },
5436 },
7cf51e48
JW
5437 },
5438};
5439static struct snd_kcontrol_new alc260_test_mixer[] = {
5440 /* Output driver widgets */
5441 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5442 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5443 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5444 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5445 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5446 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5447
a1e8d2da
JW
5448 /* Modes for retasking pin widgets
5449 * Note: the ALC260 doesn't seem to act on requests to enable mic
5450 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5451 * mention this restriction. At this stage it's not clear whether
5452 * this behaviour is intentional or is a hardware bug in chip
5453 * revisions available at least up until early 2006. Therefore for
5454 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5455 * choices, but if it turns out that the lack of mic bias for these
5456 * NIDs is intentional we could change their modes from
5457 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5458 */
7cf51e48
JW
5459 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5460 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5461 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5462 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5463 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5464 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5465
5466 /* Loopback mixer controls */
5467 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5468 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5469 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5470 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5471 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5472 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5473 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5474 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5475 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5476 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
5477 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5478 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5479 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5480 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
5481
5482 /* Controls for GPIO pins, assuming they are configured as outputs */
5483 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5484 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5485 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5486 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5487
92621f13
JW
5488 /* Switches to allow the digital IO pins to be enabled. The datasheet
5489 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 5490 * make this output available should provide clarification.
92621f13
JW
5491 */
5492 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5493 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5494
f8225f6d
JW
5495 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5496 * this output to turn on an external amplifier.
5497 */
5498 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5499 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5500
7cf51e48
JW
5501 { } /* end */
5502};
5503static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
5504 /* Enable all GPIOs as outputs with an initial value of 0 */
5505 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5506 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5507 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5508
7cf51e48
JW
5509 /* Enable retasking pins as output, initially without power amp */
5510 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5511 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5514 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5515 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5516
92621f13
JW
5517 /* Disable digital (SPDIF) pins initially, but users can enable
5518 * them via a mixer switch. In the case of SPDIF-out, this initverb
5519 * payload also sets the generation to 0, output to be in "consumer"
5520 * PCM format, copyright asserted, no pre-emphasis and no validity
5521 * control.
5522 */
7cf51e48
JW
5523 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5524 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5525
ea1fb29a 5526 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5527 * OUT1 sum bus when acting as an output.
5528 */
5529 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5530 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5531 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5532 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5533
5534 /* Start with output sum widgets muted and their output gains at min */
5535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5542 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5543 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5544
cdcd9268
JW
5545 /* Unmute retasking pin widget output buffers since the default
5546 * state appears to be output. As the pin mode is changed by the
5547 * user the pin mode control will take care of enabling the pin's
5548 * input/output buffers as needed.
5549 */
7cf51e48
JW
5550 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5551 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5554 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5555 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5556 /* Also unmute the mono-out pin widget */
5557 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5558
7cf51e48
JW
5559 /* Mute capture amp left and right */
5560 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5561 /* Set ADC connection select to match default mixer setting (mic1
5562 * pin)
7cf51e48
JW
5563 */
5564 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5565
5566 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5567 * set ADC connection to mic1 pin
7cf51e48
JW
5568 */
5569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5570 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5571
5572 /* Mute all inputs to mixer widget (even unconnected ones) */
5573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5581
5582 { }
5583};
5584#endif
5585
6330079f
TI
5586#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5587#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5588
a3bcba38
TI
5589#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5590#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5591
df694daa
KY
5592/*
5593 * for BIOS auto-configuration
5594 */
16ded525 5595
df694daa 5596static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5597 const char *pfx, int *vol_bits)
df694daa
KY
5598{
5599 hda_nid_t nid_vol;
5600 unsigned long vol_val, sw_val;
5601 char name[32];
5602 int err;
5603
5604 if (nid >= 0x0f && nid < 0x11) {
5605 nid_vol = nid - 0x7;
5606 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5607 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5608 } else if (nid == 0x11) {
5609 nid_vol = nid - 0x7;
5610 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5611 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5612 } else if (nid >= 0x12 && nid <= 0x15) {
5613 nid_vol = 0x08;
5614 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5615 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5616 } else
5617 return 0; /* N/A */
ea1fb29a 5618
863b4518
TI
5619 if (!(*vol_bits & (1 << nid_vol))) {
5620 /* first control for the volume widget */
5621 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5622 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5623 if (err < 0)
5624 return err;
5625 *vol_bits |= (1 << nid_vol);
5626 }
df694daa 5627 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
5628 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5629 if (err < 0)
df694daa
KY
5630 return err;
5631 return 1;
5632}
5633
5634/* add playback controls from the parsed DAC table */
5635static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5636 const struct auto_pin_cfg *cfg)
5637{
5638 hda_nid_t nid;
5639 int err;
863b4518 5640 int vols = 0;
df694daa
KY
5641
5642 spec->multiout.num_dacs = 1;
5643 spec->multiout.dac_nids = spec->private_dac_nids;
5644 spec->multiout.dac_nids[0] = 0x02;
5645
5646 nid = cfg->line_out_pins[0];
5647 if (nid) {
863b4518 5648 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
df694daa
KY
5649 if (err < 0)
5650 return err;
5651 }
5652
82bc955f 5653 nid = cfg->speaker_pins[0];
df694daa 5654 if (nid) {
863b4518 5655 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
5656 if (err < 0)
5657 return err;
5658 }
5659
eb06ed8f 5660 nid = cfg->hp_pins[0];
df694daa 5661 if (nid) {
863b4518
TI
5662 err = alc260_add_playback_controls(spec, nid, "Headphone",
5663 &vols);
df694daa
KY
5664 if (err < 0)
5665 return err;
5666 }
f12ab1e0 5667 return 0;
df694daa
KY
5668}
5669
5670/* create playback/capture controls for input pins */
5671static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5672 const struct auto_pin_cfg *cfg)
5673{
61b9b9b1 5674 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
5675 int i, err, idx;
5676
5677 for (i = 0; i < AUTO_PIN_LAST; i++) {
5678 if (cfg->input_pins[i] >= 0x12) {
5679 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5680 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5681 auto_pin_cfg_labels[i], idx,
5682 0x07);
df694daa
KY
5683 if (err < 0)
5684 return err;
f12ab1e0
TI
5685 imux->items[imux->num_items].label =
5686 auto_pin_cfg_labels[i];
df694daa
KY
5687 imux->items[imux->num_items].index = idx;
5688 imux->num_items++;
5689 }
f12ab1e0 5690 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5691 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5692 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5693 auto_pin_cfg_labels[i], idx,
5694 0x07);
df694daa
KY
5695 if (err < 0)
5696 return err;
f12ab1e0
TI
5697 imux->items[imux->num_items].label =
5698 auto_pin_cfg_labels[i];
df694daa
KY
5699 imux->items[imux->num_items].index = idx;
5700 imux->num_items++;
5701 }
5702 }
5703 return 0;
5704}
5705
5706static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5707 hda_nid_t nid, int pin_type,
5708 int sel_idx)
5709{
f6c7e546 5710 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5711 /* need the manual connection? */
5712 if (nid >= 0x12) {
5713 int idx = nid - 0x12;
5714 snd_hda_codec_write(codec, idx + 0x0b, 0,
5715 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5716 }
5717}
5718
5719static void alc260_auto_init_multi_out(struct hda_codec *codec)
5720{
5721 struct alc_spec *spec = codec->spec;
5722 hda_nid_t nid;
5723
f12ab1e0 5724 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5725 if (nid) {
5726 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5727 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5728 }
ea1fb29a 5729
82bc955f 5730 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5731 if (nid)
5732 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5733
eb06ed8f 5734 nid = spec->autocfg.hp_pins[0];
df694daa 5735 if (nid)
baba8ee9 5736 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5737}
df694daa
KY
5738
5739#define ALC260_PIN_CD_NID 0x16
5740static void alc260_auto_init_analog_input(struct hda_codec *codec)
5741{
5742 struct alc_spec *spec = codec->spec;
5743 int i;
5744
5745 for (i = 0; i < AUTO_PIN_LAST; i++) {
5746 hda_nid_t nid = spec->autocfg.input_pins[i];
5747 if (nid >= 0x12) {
23f0c048 5748 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5749 if (nid != ALC260_PIN_CD_NID &&
5750 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5751 snd_hda_codec_write(codec, nid, 0,
5752 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5753 AMP_OUT_MUTE);
5754 }
5755 }
5756}
5757
5758/*
5759 * generic initialization of ADC, input mixers and output mixers
5760 */
5761static struct hda_verb alc260_volume_init_verbs[] = {
5762 /*
5763 * Unmute ADC0-1 and set the default input to mic-in
5764 */
5765 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5766 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5767 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5768 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5769
df694daa
KY
5770 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5771 * mixer widget
f12ab1e0
TI
5772 * Note: PASD motherboards uses the Line In 2 as the input for
5773 * front panel mic (mic 2)
df694daa
KY
5774 */
5775 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5776 /* mute analog inputs */
5777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5782
5783 /*
5784 * Set up output mixers (0x08 - 0x0a)
5785 */
5786 /* set vol=0 to output mixers */
5787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5789 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5790 /* set up input amps for analog loopback */
5791 /* Amp Indices: DAC = 0, mixer = 1 */
5792 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5793 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5795 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5798
df694daa
KY
5799 { }
5800};
5801
5802static int alc260_parse_auto_config(struct hda_codec *codec)
5803{
5804 struct alc_spec *spec = codec->spec;
df694daa
KY
5805 int err;
5806 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5807
f12ab1e0
TI
5808 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5809 alc260_ignore);
5810 if (err < 0)
df694daa 5811 return err;
f12ab1e0
TI
5812 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5813 if (err < 0)
4a471b7d 5814 return err;
603c4019 5815 if (!spec->kctls.list)
df694daa 5816 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5817 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5818 if (err < 0)
df694daa
KY
5819 return err;
5820
5821 spec->multiout.max_channels = 2;
5822
0852d7a6 5823 if (spec->autocfg.dig_outs)
df694daa 5824 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 5825 if (spec->kctls.list)
d88897ea 5826 add_mixer(spec, spec->kctls.list);
df694daa 5827
d88897ea 5828 add_verb(spec, alc260_volume_init_verbs);
df694daa 5829
a1e8d2da 5830 spec->num_mux_defs = 1;
61b9b9b1 5831 spec->input_mux = &spec->private_imux[0];
df694daa 5832
4a79ba34
TI
5833 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5834
df694daa
KY
5835 return 1;
5836}
5837
ae6b813a
TI
5838/* additional initialization for auto-configuration model */
5839static void alc260_auto_init(struct hda_codec *codec)
df694daa 5840{
f6c7e546 5841 struct alc_spec *spec = codec->spec;
df694daa
KY
5842 alc260_auto_init_multi_out(codec);
5843 alc260_auto_init_analog_input(codec);
f6c7e546 5844 if (spec->unsol_event)
7fb0d78f 5845 alc_inithook(codec);
df694daa
KY
5846}
5847
cb53c626
TI
5848#ifdef CONFIG_SND_HDA_POWER_SAVE
5849static struct hda_amp_list alc260_loopbacks[] = {
5850 { 0x07, HDA_INPUT, 0 },
5851 { 0x07, HDA_INPUT, 1 },
5852 { 0x07, HDA_INPUT, 2 },
5853 { 0x07, HDA_INPUT, 3 },
5854 { 0x07, HDA_INPUT, 4 },
5855 { } /* end */
5856};
5857#endif
5858
df694daa
KY
5859/*
5860 * ALC260 configurations
5861 */
f5fcc13c
TI
5862static const char *alc260_models[ALC260_MODEL_LAST] = {
5863 [ALC260_BASIC] = "basic",
5864 [ALC260_HP] = "hp",
5865 [ALC260_HP_3013] = "hp-3013",
2922c9af 5866 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
5867 [ALC260_FUJITSU_S702X] = "fujitsu",
5868 [ALC260_ACER] = "acer",
bc9f98a9
KY
5869 [ALC260_WILL] = "will",
5870 [ALC260_REPLACER_672V] = "replacer",
cc959489 5871 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 5872#ifdef CONFIG_SND_DEBUG
f5fcc13c 5873 [ALC260_TEST] = "test",
7cf51e48 5874#endif
f5fcc13c
TI
5875 [ALC260_AUTO] = "auto",
5876};
5877
5878static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5879 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5880 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 5881 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 5882 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5883 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 5884 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 5885 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 5886 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
5887 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5888 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5889 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5890 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5891 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5892 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5893 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5894 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5895 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5896 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5897 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5898 {}
5899};
5900
5901static struct alc_config_preset alc260_presets[] = {
5902 [ALC260_BASIC] = {
5903 .mixers = { alc260_base_output_mixer,
45bdd1c1 5904 alc260_input_mixer },
df694daa
KY
5905 .init_verbs = { alc260_init_verbs },
5906 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5907 .dac_nids = alc260_dac_nids,
f9e336f6 5908 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
5909 .adc_nids = alc260_adc_nids,
5910 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5911 .channel_mode = alc260_modes,
5912 .input_mux = &alc260_capture_source,
5913 },
5914 [ALC260_HP] = {
bec15c3a 5915 .mixers = { alc260_hp_output_mixer,
f9e336f6 5916 alc260_input_mixer },
bec15c3a
TI
5917 .init_verbs = { alc260_init_verbs,
5918 alc260_hp_unsol_verbs },
df694daa
KY
5919 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5920 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5921 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5922 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
5923 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5924 .channel_mode = alc260_modes,
5925 .input_mux = &alc260_capture_source,
bec15c3a
TI
5926 .unsol_event = alc260_hp_unsol_event,
5927 .init_hook = alc260_hp_automute,
df694daa 5928 },
3f878308
KY
5929 [ALC260_HP_DC7600] = {
5930 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 5931 alc260_input_mixer },
3f878308
KY
5932 .init_verbs = { alc260_init_verbs,
5933 alc260_hp_dc7600_verbs },
5934 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5935 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5936 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5937 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
5938 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5939 .channel_mode = alc260_modes,
5940 .input_mux = &alc260_capture_source,
5941 .unsol_event = alc260_hp_3012_unsol_event,
5942 .init_hook = alc260_hp_3012_automute,
5943 },
df694daa
KY
5944 [ALC260_HP_3013] = {
5945 .mixers = { alc260_hp_3013_mixer,
f9e336f6 5946 alc260_input_mixer },
bec15c3a
TI
5947 .init_verbs = { alc260_hp_3013_init_verbs,
5948 alc260_hp_3013_unsol_verbs },
df694daa
KY
5949 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5950 .dac_nids = alc260_dac_nids,
f9e336f6
TI
5951 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5952 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
5953 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5954 .channel_mode = alc260_modes,
5955 .input_mux = &alc260_capture_source,
bec15c3a
TI
5956 .unsol_event = alc260_hp_3013_unsol_event,
5957 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5958 },
5959 [ALC260_FUJITSU_S702X] = {
f9e336f6 5960 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
5961 .init_verbs = { alc260_fujitsu_init_verbs },
5962 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5963 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5964 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5965 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5966 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5967 .channel_mode = alc260_modes,
a1e8d2da
JW
5968 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5969 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5970 },
0bfc90e9 5971 [ALC260_ACER] = {
f9e336f6 5972 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
5973 .init_verbs = { alc260_acer_init_verbs },
5974 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5975 .dac_nids = alc260_dac_nids,
5976 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5977 .adc_nids = alc260_dual_adc_nids,
5978 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5979 .channel_mode = alc260_modes,
a1e8d2da
JW
5980 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5981 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5982 },
cc959489
MS
5983 [ALC260_FAVORIT100] = {
5984 .mixers = { alc260_favorit100_mixer },
5985 .init_verbs = { alc260_favorit100_init_verbs },
5986 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5987 .dac_nids = alc260_dac_nids,
5988 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5989 .adc_nids = alc260_dual_adc_nids,
5990 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5991 .channel_mode = alc260_modes,
5992 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5993 .input_mux = alc260_favorit100_capture_sources,
5994 },
bc9f98a9 5995 [ALC260_WILL] = {
f9e336f6 5996 .mixers = { alc260_will_mixer },
bc9f98a9
KY
5997 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5998 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5999 .dac_nids = alc260_dac_nids,
6000 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6001 .adc_nids = alc260_adc_nids,
6002 .dig_out_nid = ALC260_DIGOUT_NID,
6003 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6004 .channel_mode = alc260_modes,
6005 .input_mux = &alc260_capture_source,
6006 },
6007 [ALC260_REPLACER_672V] = {
f9e336f6 6008 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6009 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6010 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6011 .dac_nids = alc260_dac_nids,
6012 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6013 .adc_nids = alc260_adc_nids,
6014 .dig_out_nid = ALC260_DIGOUT_NID,
6015 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6016 .channel_mode = alc260_modes,
6017 .input_mux = &alc260_capture_source,
6018 .unsol_event = alc260_replacer_672v_unsol_event,
6019 .init_hook = alc260_replacer_672v_automute,
6020 },
7cf51e48
JW
6021#ifdef CONFIG_SND_DEBUG
6022 [ALC260_TEST] = {
f9e336f6 6023 .mixers = { alc260_test_mixer },
7cf51e48
JW
6024 .init_verbs = { alc260_test_init_verbs },
6025 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6026 .dac_nids = alc260_test_dac_nids,
6027 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6028 .adc_nids = alc260_test_adc_nids,
6029 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6030 .channel_mode = alc260_modes,
a1e8d2da
JW
6031 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6032 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6033 },
6034#endif
df694daa
KY
6035};
6036
6037static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6038{
6039 struct alc_spec *spec;
df694daa 6040 int err, board_config;
1da177e4 6041
e560d8d8 6042 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6043 if (spec == NULL)
6044 return -ENOMEM;
6045
6046 codec->spec = spec;
6047
f5fcc13c
TI
6048 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6049 alc260_models,
6050 alc260_cfg_tbl);
6051 if (board_config < 0) {
9c7f852e
TI
6052 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6053 "trying auto-probe from BIOS...\n");
df694daa 6054 board_config = ALC260_AUTO;
16ded525 6055 }
1da177e4 6056
df694daa
KY
6057 if (board_config == ALC260_AUTO) {
6058 /* automatic parse from the BIOS config */
6059 err = alc260_parse_auto_config(codec);
6060 if (err < 0) {
6061 alc_free(codec);
6062 return err;
f12ab1e0 6063 } else if (!err) {
9c7f852e
TI
6064 printk(KERN_INFO
6065 "hda_codec: Cannot set up configuration "
6066 "from BIOS. Using base mode...\n");
df694daa
KY
6067 board_config = ALC260_BASIC;
6068 }
a9430dd8 6069 }
e9edcee0 6070
680cd536
KK
6071 err = snd_hda_attach_beep_device(codec, 0x1);
6072 if (err < 0) {
6073 alc_free(codec);
6074 return err;
6075 }
6076
df694daa
KY
6077 if (board_config != ALC260_AUTO)
6078 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
6079
6080 spec->stream_name_analog = "ALC260 Analog";
6081 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6082 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6083
a3bcba38
TI
6084 spec->stream_name_digital = "ALC260 Digital";
6085 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6086 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6087
4ef0ef19
TI
6088 if (!spec->adc_nids && spec->input_mux) {
6089 /* check whether NID 0x04 is valid */
6090 unsigned int wcap = get_wcaps(codec, 0x04);
6091 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6092 /* get type */
6093 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6094 spec->adc_nids = alc260_adc_nids_alt;
6095 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6096 } else {
6097 spec->adc_nids = alc260_adc_nids;
6098 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6099 }
6100 }
f9e336f6 6101 set_capture_mixer(spec);
45bdd1c1 6102 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6103
2134ea4f
TI
6104 spec->vmaster_nid = 0x08;
6105
1da177e4 6106 codec->patch_ops = alc_patch_ops;
df694daa 6107 if (board_config == ALC260_AUTO)
ae6b813a 6108 spec->init_hook = alc260_auto_init;
cb53c626
TI
6109#ifdef CONFIG_SND_HDA_POWER_SAVE
6110 if (!spec->loopback.amplist)
6111 spec->loopback.amplist = alc260_loopbacks;
6112#endif
daead538 6113 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
6114
6115 return 0;
6116}
6117
e9edcee0 6118
1da177e4
LT
6119/*
6120 * ALC882 support
6121 *
6122 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6123 * configuration. Each pin widget can choose any input DACs and a mixer.
6124 * Each ADC is connected from a mixer of all inputs. This makes possible
6125 * 6-channel independent captures.
6126 *
6127 * In addition, an independent DAC for the multi-playback (not used in this
6128 * driver yet).
6129 */
df694daa
KY
6130#define ALC882_DIGOUT_NID 0x06
6131#define ALC882_DIGIN_NID 0x0a
1da177e4 6132
d2a6d7dc 6133static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6134 { 8, NULL }
6135};
6136
6137static hda_nid_t alc882_dac_nids[4] = {
6138 /* front, rear, clfe, rear_surr */
6139 0x02, 0x03, 0x04, 0x05
6140};
6141
df694daa
KY
6142/* identical with ALC880 */
6143#define alc882_adc_nids alc880_adc_nids
6144#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 6145
e1406348
TI
6146static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6147static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6148
1da177e4
LT
6149/* input MUX */
6150/* FIXME: should be a matrix-type input source selection */
6151
6152static struct hda_input_mux alc882_capture_source = {
6153 .num_items = 4,
6154 .items = {
6155 { "Mic", 0x0 },
6156 { "Front Mic", 0x1 },
6157 { "Line", 0x2 },
6158 { "CD", 0x4 },
6159 },
6160};
41d5545d
KS
6161
6162static struct hda_input_mux mb5_capture_source = {
6163 .num_items = 3,
6164 .items = {
6165 { "Mic", 0x1 },
6166 { "Line", 0x2 },
6167 { "CD", 0x4 },
6168 },
6169};
6170
272a527c
KY
6171/*
6172 * 2ch mode
6173 */
6174static struct hda_verb alc882_3ST_ch2_init[] = {
6175 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6176 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6177 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6178 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6179 { } /* end */
6180};
6181
6182/*
6183 * 6ch mode
6184 */
6185static struct hda_verb alc882_3ST_ch6_init[] = {
6186 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6187 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6188 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6189 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6190 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6191 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6192 { } /* end */
6193};
6194
6195static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6196 { 2, alc882_3ST_ch2_init },
6197 { 6, alc882_3ST_ch6_init },
6198};
6199
df694daa
KY
6200/*
6201 * 6ch mode
6202 */
6203static struct hda_verb alc882_sixstack_ch6_init[] = {
6204 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6205 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6206 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6207 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6208 { } /* end */
6209};
6210
6211/*
6212 * 8ch mode
6213 */
6214static struct hda_verb alc882_sixstack_ch8_init[] = {
6215 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6216 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6217 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6218 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6219 { } /* end */
6220};
6221
6222static struct hda_channel_mode alc882_sixstack_modes[2] = {
6223 { 6, alc882_sixstack_ch6_init },
6224 { 8, alc882_sixstack_ch8_init },
6225};
6226
87350ad0
TI
6227/*
6228 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6229 */
6230
6231/*
6232 * 2ch mode
6233 */
6234static struct hda_verb alc885_mbp_ch2_init[] = {
6235 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6236 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6237 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6238 { } /* end */
6239};
6240
6241/*
6242 * 6ch mode
6243 */
6244static struct hda_verb alc885_mbp_ch6_init[] = {
6245 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6246 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6247 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6248 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6249 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6250 { } /* end */
6251};
6252
6253static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6254 { 2, alc885_mbp_ch2_init },
6255 { 6, alc885_mbp_ch6_init },
6256};
6257
6258
1da177e4
LT
6259/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6260 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6261 */
c8b6bf9b 6262static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 6263 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 6264 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 6265 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 6266 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
6267 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6268 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
6269 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6270 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 6271 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 6272 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
6273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6276 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6277 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6279 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
6280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6281 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6282 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 6283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
6284 { } /* end */
6285};
6286
87350ad0 6287static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
6288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6289 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6290 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6291 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6293 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
6294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6295 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 6296 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
6297 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6298 { } /* end */
6299};
41d5545d
KS
6300
6301static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6303 HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
6304 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6305 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
6306 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6307 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6309 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6310 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6311 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6312 { } /* end */
6313};
bdd148a3
KY
6314static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6315 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6316 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6317 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6318 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6319 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6320 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
6324 { } /* end */
6325};
6326
272a527c
KY
6327static struct snd_kcontrol_new alc882_targa_mixer[] = {
6328 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6329 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6337 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6338 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6339 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 6340 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
6341 { } /* end */
6342};
6343
6344/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6345 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6346 */
6347static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6349 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6351 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6352 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6353 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6354 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6355 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6356 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6357 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6360 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6361 { } /* end */
6362};
6363
914759b7
TI
6364static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6368 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6369 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6370 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6371 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
6375 { } /* end */
6376};
6377
df694daa
KY
6378static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6379 {
6380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6381 .name = "Channel Mode",
6382 .info = alc_ch_mode_info,
6383 .get = alc_ch_mode_get,
6384 .put = alc_ch_mode_put,
6385 },
6386 { } /* end */
6387};
6388
1da177e4
LT
6389static struct hda_verb alc882_init_verbs[] = {
6390 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
6391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6394 /* Rear mixer */
05acb863
TI
6395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6398 /* CLFE mixer */
05acb863
TI
6399 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6402 /* Side mixer */
05acb863
TI
6403 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6406
e9edcee0 6407 /* Front Pin: output 0 (0x0c) */
05acb863 6408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6409 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6410 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 6411 /* Rear Pin: output 1 (0x0d) */
05acb863 6412 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6413 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6414 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 6415 /* CLFE Pin: output 2 (0x0e) */
05acb863 6416 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6417 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6418 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 6419 /* Side Pin: output 3 (0x0f) */
05acb863 6420 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6421 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6422 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 6423 /* Mic (rear) pin: input vref at 80% */
16ded525 6424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6425 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6426 /* Front Mic pin: input vref at 80% */
16ded525 6427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6428 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6429 /* Line In pin: input */
05acb863 6430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
6431 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6432 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6434 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6435 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6436 /* CD pin widget for input */
05acb863 6437 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
6438
6439 /* FIXME: use matrix-type input source selection */
6440 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6441 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
6442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6446 /* Input mixer2 */
05acb863
TI
6447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6451 /* Input mixer3 */
05acb863
TI
6452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6456 /* ADC1: mute amp left and right */
6457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6458 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6459 /* ADC2: mute amp left and right */
6460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6461 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6462 /* ADC3: mute amp left and right */
6463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
6465
6466 { }
6467};
6468
4b146cb0
TI
6469static struct hda_verb alc882_eapd_verbs[] = {
6470 /* change to EAPD mode */
6471 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 6472 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 6473 { }
4b146cb0
TI
6474};
6475
9102cd1c
TD
6476/* Mac Pro test */
6477static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6479 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 6483 /* FIXME: this looks suspicious...
9102cd1c
TD
6484 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6485 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 6486 */
9102cd1c
TD
6487 { } /* end */
6488};
6489
6490static struct hda_verb alc882_macpro_init_verbs[] = {
6491 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6492 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6495 /* Front Pin: output 0 (0x0c) */
6496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6498 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6499 /* Front Mic pin: input vref at 80% */
6500 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6501 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6502 /* Speaker: output */
6503 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6504 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6505 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6506 /* Headphone output (output 0 - 0x0c) */
6507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6509 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6510
6511 /* FIXME: use matrix-type input source selection */
6512 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6513 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6514 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6518 /* Input mixer2 */
6519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6523 /* Input mixer3 */
6524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6528 /* ADC1: mute amp left and right */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6531 /* ADC2: mute amp left and right */
6532 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6534 /* ADC3: mute amp left and right */
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6536 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6537
6538 { }
6539};
f12ab1e0 6540
41d5545d
KS
6541/* Macbook 5,1 */
6542static struct hda_verb alc885_mb5_init_verbs[] = {
6543 /* Front mixer */
6544 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6546 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6547 /* LineOut mixer */
6548 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6551 /* Front Pin: output 0 (0x0d) */
6552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6554 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
6555 /* HP Pin: output 0 (0x0c) */
6556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6557 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6558 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6559 /* Front Mic pin: input vref at 80% */
6560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6562 /* Line In pin */
6563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6565
6566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6570 { }
6571};
6572
87350ad0
TI
6573/* Macbook Pro rev3 */
6574static struct hda_verb alc885_mbp3_init_verbs[] = {
6575 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6576 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6579 /* Rear mixer */
6580 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6583 /* Front Pin: output 0 (0x0c) */
6584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6585 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6586 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6587 /* HP Pin: output 0 (0x0d) */
6588 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6591 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6592 /* Mic (rear) pin: input vref at 80% */
6593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6594 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6595 /* Front Mic pin: input vref at 80% */
6596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6598 /* Line In pin: use output 1 when in LineOut mode */
6599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6601 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6602
6603 /* FIXME: use matrix-type input source selection */
6604 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6605 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6610 /* Input mixer2 */
6611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6615 /* Input mixer3 */
6616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6620 /* ADC1: mute amp left and right */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6622 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6623 /* ADC2: mute amp left and right */
6624 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6625 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6626 /* ADC3: mute amp left and right */
6627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6628 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6629
6630 { }
6631};
6632
c54728d8
NF
6633/* iMac 24 mixer. */
6634static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6635 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6636 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6637 { } /* end */
6638};
6639
6640/* iMac 24 init verbs. */
6641static struct hda_verb alc885_imac24_init_verbs[] = {
6642 /* Internal speakers: output 0 (0x0c) */
6643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6644 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6645 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6646 /* Internal speakers: output 0 (0x0c) */
6647 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6649 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6650 /* Headphone: output 0 (0x0c) */
6651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6652 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6653 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6654 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6655 /* Front Mic: input vref at 80% */
6656 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6657 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6658 { }
6659};
6660
6661/* Toggle speaker-output according to the hp-jack state */
a9fd4f3f 6662static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
c54728d8 6663{
a9fd4f3f 6664 struct alc_spec *spec = codec->spec;
c54728d8 6665
a9fd4f3f
TI
6666 spec->autocfg.hp_pins[0] = 0x14;
6667 spec->autocfg.speaker_pins[0] = 0x18;
6668 spec->autocfg.speaker_pins[1] = 0x1a;
6669 alc_automute_amp(codec);
c54728d8
NF
6670}
6671
a9fd4f3f 6672static void alc885_mbp3_init_hook(struct hda_codec *codec)
87350ad0 6673{
a9fd4f3f 6674 struct alc_spec *spec = codec->spec;
87350ad0 6675
a9fd4f3f
TI
6676 spec->autocfg.hp_pins[0] = 0x15;
6677 spec->autocfg.speaker_pins[0] = 0x14;
6678 alc_automute_amp(codec);
87350ad0
TI
6679}
6680
6681
272a527c
KY
6682static struct hda_verb alc882_targa_verbs[] = {
6683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6685
6686 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6687 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6688
272a527c
KY
6689 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6690 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6691 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6692
6693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6694 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6695 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6696 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6697 { } /* end */
6698};
6699
6700/* toggle speaker-output according to the hp-jack state */
6701static void alc882_targa_automute(struct hda_codec *codec)
6702{
a9fd4f3f
TI
6703 struct alc_spec *spec = codec->spec;
6704 alc_automute_amp(codec);
82beb8fd 6705 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
6706 spec->jack_present ? 1 : 3);
6707}
6708
6709static void alc882_targa_init_hook(struct hda_codec *codec)
6710{
6711 struct alc_spec *spec = codec->spec;
6712
6713 spec->autocfg.hp_pins[0] = 0x14;
6714 spec->autocfg.speaker_pins[0] = 0x1b;
6715 alc882_targa_automute(codec);
272a527c
KY
6716}
6717
6718static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6719{
a9fd4f3f 6720 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 6721 alc882_targa_automute(codec);
272a527c
KY
6722}
6723
6724static struct hda_verb alc882_asus_a7j_verbs[] = {
6725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6727
6728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6730 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6731
272a527c
KY
6732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6734 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6735
6736 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6737 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6738 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6739 { } /* end */
6740};
6741
914759b7
TI
6742static struct hda_verb alc882_asus_a7m_verbs[] = {
6743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6745
6746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6748 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6749
914759b7
TI
6750 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6752 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6753
6754 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6755 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6756 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6757 { } /* end */
6758};
6759
9102cd1c
TD
6760static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6761{
6762 unsigned int gpiostate, gpiomask, gpiodir;
6763
6764 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6765 AC_VERB_GET_GPIO_DATA, 0);
6766
6767 if (!muted)
6768 gpiostate |= (1 << pin);
6769 else
6770 gpiostate &= ~(1 << pin);
6771
6772 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6773 AC_VERB_GET_GPIO_MASK, 0);
6774 gpiomask |= (1 << pin);
6775
6776 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6777 AC_VERB_GET_GPIO_DIRECTION, 0);
6778 gpiodir |= (1 << pin);
6779
6780
6781 snd_hda_codec_write(codec, codec->afg, 0,
6782 AC_VERB_SET_GPIO_MASK, gpiomask);
6783 snd_hda_codec_write(codec, codec->afg, 0,
6784 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6785
6786 msleep(1);
6787
6788 snd_hda_codec_write(codec, codec->afg, 0,
6789 AC_VERB_SET_GPIO_DATA, gpiostate);
6790}
6791
7debbe51
TI
6792/* set up GPIO at initialization */
6793static void alc885_macpro_init_hook(struct hda_codec *codec)
6794{
6795 alc882_gpio_mute(codec, 0, 0);
6796 alc882_gpio_mute(codec, 1, 0);
6797}
6798
6799/* set up GPIO and update auto-muting at initialization */
6800static void alc885_imac24_init_hook(struct hda_codec *codec)
6801{
6802 alc885_macpro_init_hook(codec);
a9fd4f3f 6803 alc885_imac24_automute_init_hook(codec);
7debbe51
TI
6804}
6805
df694daa
KY
6806/*
6807 * generic initialization of ADC, input mixers and output mixers
6808 */
6809static struct hda_verb alc882_auto_init_verbs[] = {
6810 /*
6811 * Unmute ADC0-2 and set the default input to mic-in
6812 */
6813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6814 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6815 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6816 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6817 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6818 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6819
cb53c626 6820 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6821 * mixer widget
f12ab1e0
TI
6822 * Note: PASD motherboards uses the Line In 2 as the input for
6823 * front panel mic (mic 2)
df694daa
KY
6824 */
6825 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6826 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 6831
df694daa
KY
6832 /*
6833 * Set up output mixers (0x0c - 0x0f)
6834 */
6835 /* set vol=0 to output mixers */
6836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6839 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6840 /* set up input amps for analog loopback */
6841 /* Amp Indices: DAC = 0, mixer = 1 */
6842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6844 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6850 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6851 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6852
6853 /* FIXME: use matrix-type input source selection */
6854 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6855 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6859 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6860 /* Input mixer2 */
6861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6863 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6864 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6865 /* Input mixer3 */
6866 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6869 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6870
6871 { }
6872};
6873
cb53c626
TI
6874#ifdef CONFIG_SND_HDA_POWER_SAVE
6875#define alc882_loopbacks alc880_loopbacks
6876#endif
6877
df694daa
KY
6878/* pcm configuration: identiacal with ALC880 */
6879#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6880#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6881#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6882#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6883
6884/*
6885 * configuration and preset
6886 */
f5fcc13c
TI
6887static const char *alc882_models[ALC882_MODEL_LAST] = {
6888 [ALC882_3ST_DIG] = "3stack-dig",
6889 [ALC882_6ST_DIG] = "6stack-dig",
6890 [ALC882_ARIMA] = "arima",
bdd148a3 6891 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6892 [ALC882_TARGA] = "targa",
6893 [ALC882_ASUS_A7J] = "asus-a7j",
6894 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6895 [ALC885_MACPRO] = "macpro",
41d5545d 6896 [ALC885_MB5] = "mb5",
87350ad0 6897 [ALC885_MBP3] = "mbp3",
c54728d8 6898 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6899 [ALC882_AUTO] = "auto",
6900};
6901
6902static struct snd_pci_quirk alc882_cfg_tbl[] = {
6903 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6904 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6905 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6906 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6907 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6908 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6909 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6910 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6911 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6912 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6913 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6914 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6915 {}
6916};
6917
6918static struct alc_config_preset alc882_presets[] = {
6919 [ALC882_3ST_DIG] = {
6920 .mixers = { alc882_base_mixer },
6921 .init_verbs = { alc882_init_verbs },
6922 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6923 .dac_nids = alc882_dac_nids,
6924 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6925 .dig_in_nid = ALC882_DIGIN_NID,
6926 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6927 .channel_mode = alc882_ch_modes,
4e195a7b 6928 .need_dac_fix = 1,
df694daa
KY
6929 .input_mux = &alc882_capture_source,
6930 },
6931 [ALC882_6ST_DIG] = {
6932 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6933 .init_verbs = { alc882_init_verbs },
6934 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6935 .dac_nids = alc882_dac_nids,
6936 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6937 .dig_in_nid = ALC882_DIGIN_NID,
6938 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6939 .channel_mode = alc882_sixstack_modes,
6940 .input_mux = &alc882_capture_source,
6941 },
4b146cb0
TI
6942 [ALC882_ARIMA] = {
6943 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6944 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6945 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6946 .dac_nids = alc882_dac_nids,
6947 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6948 .channel_mode = alc882_sixstack_modes,
6949 .input_mux = &alc882_capture_source,
6950 },
bdd148a3
KY
6951 [ALC882_W2JC] = {
6952 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6953 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6954 alc880_gpio1_init_verbs },
6955 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6956 .dac_nids = alc882_dac_nids,
6957 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6958 .channel_mode = alc880_threestack_modes,
6959 .need_dac_fix = 1,
6960 .input_mux = &alc882_capture_source,
6961 .dig_out_nid = ALC882_DIGOUT_NID,
6962 },
87350ad0
TI
6963 [ALC885_MBP3] = {
6964 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6965 .init_verbs = { alc885_mbp3_init_verbs,
6966 alc880_gpio1_init_verbs },
6967 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6968 .dac_nids = alc882_dac_nids,
6969 .channel_mode = alc885_mbp_6ch_modes,
6970 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6971 .input_mux = &alc882_capture_source,
6972 .dig_out_nid = ALC882_DIGOUT_NID,
6973 .dig_in_nid = ALC882_DIGIN_NID,
a9fd4f3f
TI
6974 .unsol_event = alc_automute_amp_unsol_event,
6975 .init_hook = alc885_mbp3_init_hook,
87350ad0 6976 },
41d5545d
KS
6977 [ALC885_MB5] = {
6978 .mixers = { alc885_mb5_mixer },
6979 .init_verbs = { alc885_mb5_init_verbs,
6980 alc880_gpio1_init_verbs },
6981 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6982 .dac_nids = alc882_dac_nids,
6983 .channel_mode = alc885_mbp_6ch_modes,
6984 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6985 .input_mux = &mb5_capture_source,
6986 .dig_out_nid = ALC882_DIGOUT_NID,
6987 .dig_in_nid = ALC882_DIGIN_NID,
6988 },
9102cd1c
TD
6989 [ALC885_MACPRO] = {
6990 .mixers = { alc882_macpro_mixer },
6991 .init_verbs = { alc882_macpro_init_verbs },
6992 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6993 .dac_nids = alc882_dac_nids,
6994 .dig_out_nid = ALC882_DIGOUT_NID,
6995 .dig_in_nid = ALC882_DIGIN_NID,
6996 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6997 .channel_mode = alc882_ch_modes,
6998 .input_mux = &alc882_capture_source,
7debbe51 6999 .init_hook = alc885_macpro_init_hook,
9102cd1c 7000 },
c54728d8
NF
7001 [ALC885_IMAC24] = {
7002 .mixers = { alc885_imac24_mixer },
7003 .init_verbs = { alc885_imac24_init_verbs },
7004 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7005 .dac_nids = alc882_dac_nids,
7006 .dig_out_nid = ALC882_DIGOUT_NID,
7007 .dig_in_nid = ALC882_DIGIN_NID,
7008 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7009 .channel_mode = alc882_ch_modes,
7010 .input_mux = &alc882_capture_source,
a9fd4f3f 7011 .unsol_event = alc_automute_amp_unsol_event,
7debbe51 7012 .init_hook = alc885_imac24_init_hook,
c54728d8 7013 },
272a527c 7014 [ALC882_TARGA] = {
f9e336f6 7015 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
272a527c
KY
7016 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7017 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7018 .dac_nids = alc882_dac_nids,
7019 .dig_out_nid = ALC882_DIGOUT_NID,
7020 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7021 .adc_nids = alc882_adc_nids,
e1406348 7022 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
7023 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7024 .channel_mode = alc882_3ST_6ch_modes,
7025 .need_dac_fix = 1,
7026 .input_mux = &alc882_capture_source,
7027 .unsol_event = alc882_targa_unsol_event,
a9fd4f3f 7028 .init_hook = alc882_targa_init_hook,
272a527c
KY
7029 },
7030 [ALC882_ASUS_A7J] = {
f9e336f6 7031 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
272a527c
KY
7032 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7033 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7034 .dac_nids = alc882_dac_nids,
7035 .dig_out_nid = ALC882_DIGOUT_NID,
7036 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7037 .adc_nids = alc882_adc_nids,
e1406348 7038 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
7039 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7040 .channel_mode = alc882_3ST_6ch_modes,
7041 .need_dac_fix = 1,
7042 .input_mux = &alc882_capture_source,
ea1fb29a 7043 },
914759b7
TI
7044 [ALC882_ASUS_A7M] = {
7045 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7046 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7047 alc880_gpio1_init_verbs,
7048 alc882_asus_a7m_verbs },
7049 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7050 .dac_nids = alc882_dac_nids,
7051 .dig_out_nid = ALC882_DIGOUT_NID,
7052 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7053 .channel_mode = alc880_threestack_modes,
7054 .need_dac_fix = 1,
7055 .input_mux = &alc882_capture_source,
ea1fb29a 7056 },
df694daa
KY
7057};
7058
7059
f95474ec
TI
7060/*
7061 * Pin config fixes
7062 */
ea1fb29a 7063enum {
f95474ec
TI
7064 PINFIX_ABIT_AW9D_MAX
7065};
7066
7067static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7068 { 0x15, 0x01080104 }, /* side */
7069 { 0x16, 0x01011012 }, /* rear */
7070 { 0x17, 0x01016011 }, /* clfe */
7071 { }
7072};
7073
7074static const struct alc_pincfg *alc882_pin_fixes[] = {
7075 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7076};
7077
7078static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7079 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7080 {}
7081};
7082
df694daa
KY
7083/*
7084 * BIOS auto configuration
7085 */
7086static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7087 hda_nid_t nid, int pin_type,
7088 int dac_idx)
7089{
7090 /* set as output */
7091 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7092 int idx;
7093
f6c7e546 7094 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7095 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7096 idx = 4;
7097 else
7098 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
7099 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7100
7101}
7102
7103static void alc882_auto_init_multi_out(struct hda_codec *codec)
7104{
7105 struct alc_spec *spec = codec->spec;
7106 int i;
7107
7108 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7109 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7110 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 7111 if (nid)
baba8ee9 7112 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7113 i);
df694daa
KY
7114 }
7115}
7116
7117static void alc882_auto_init_hp_out(struct hda_codec *codec)
7118{
7119 struct alc_spec *spec = codec->spec;
7120 hda_nid_t pin;
7121
eb06ed8f 7122 pin = spec->autocfg.hp_pins[0];
df694daa 7123 if (pin) /* connect to front */
f12ab1e0
TI
7124 /* use dac 0 */
7125 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
7126 pin = spec->autocfg.speaker_pins[0];
7127 if (pin)
7128 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
7129}
7130
7131#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7132#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7133
7134static void alc882_auto_init_analog_input(struct hda_codec *codec)
7135{
7136 struct alc_spec *spec = codec->spec;
7137 int i;
7138
7139 for (i = 0; i < AUTO_PIN_LAST; i++) {
7140 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
7141 if (!nid)
7142 continue;
23f0c048 7143 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7194cae6
TI
7144 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7145 snd_hda_codec_write(codec, nid, 0,
7146 AC_VERB_SET_AMP_GAIN_MUTE,
7147 AMP_OUT_MUTE);
df694daa
KY
7148 }
7149}
7150
f511b01c
TI
7151static void alc882_auto_init_input_src(struct hda_codec *codec)
7152{
7153 struct alc_spec *spec = codec->spec;
f511b01c
TI
7154 int c;
7155
7156 for (c = 0; c < spec->num_adc_nids; c++) {
7157 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7158 hda_nid_t nid = spec->capsrc_nids[c];
b98b7b34
HRK
7159 unsigned int mux_idx;
7160 const struct hda_input_mux *imux;
f511b01c
TI
7161 int conns, mute, idx, item;
7162
7163 conns = snd_hda_get_connections(codec, nid, conn_list,
7164 ARRAY_SIZE(conn_list));
7165 if (conns < 0)
7166 continue;
b98b7b34
HRK
7167 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7168 imux = &spec->input_mux[mux_idx];
f511b01c
TI
7169 for (idx = 0; idx < conns; idx++) {
7170 /* if the current connection is the selected one,
7171 * unmute it as default - otherwise mute it
7172 */
7173 mute = AMP_IN_MUTE(idx);
7174 for (item = 0; item < imux->num_items; item++) {
7175 if (imux->items[item].index == idx) {
7176 if (spec->cur_mux[c] == item)
7177 mute = AMP_IN_UNMUTE(idx);
7178 break;
7179 }
7180 }
b98b7b34
HRK
7181 /* check if we have a selector or mixer
7182 * we could check for the widget type instead, but
7183 * just check for Amp-In presence (in case of mixer
7184 * without amp-in there is something wrong, this
7185 * function shouldn't be used or capsrc nid is wrong)
7186 */
7187 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7188 snd_hda_codec_write(codec, nid, 0,
7189 AC_VERB_SET_AMP_GAIN_MUTE,
7190 mute);
7191 else if (mute != AMP_IN_MUTE(idx))
7192 snd_hda_codec_write(codec, nid, 0,
7193 AC_VERB_SET_CONNECT_SEL,
7194 idx);
f511b01c
TI
7195 }
7196 }
7197}
7198
776e184e
TI
7199/* add mic boosts if needed */
7200static int alc_auto_add_mic_boost(struct hda_codec *codec)
7201{
7202 struct alc_spec *spec = codec->spec;
7203 int err;
7204 hda_nid_t nid;
7205
7206 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 7207 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7208 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7209 "Mic Boost",
7210 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7211 if (err < 0)
7212 return err;
7213 }
7214 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 7215 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
7216 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7217 "Front Mic Boost",
7218 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7219 if (err < 0)
7220 return err;
7221 }
7222 return 0;
7223}
7224
df694daa
KY
7225/* almost identical with ALC880 parser... */
7226static int alc882_parse_auto_config(struct hda_codec *codec)
7227{
7228 struct alc_spec *spec = codec->spec;
7229 int err = alc880_parse_auto_config(codec);
7230
7231 if (err < 0)
7232 return err;
776e184e
TI
7233 else if (!err)
7234 return 0; /* no config found */
7235
7236 err = alc_auto_add_mic_boost(codec);
7237 if (err < 0)
7238 return err;
7239
7240 /* hack - override the init verbs */
7241 spec->init_verbs[0] = alc882_auto_init_verbs;
7242
7243 return 1; /* config found */
df694daa
KY
7244}
7245
ae6b813a
TI
7246/* additional initialization for auto-configuration model */
7247static void alc882_auto_init(struct hda_codec *codec)
df694daa 7248{
f6c7e546 7249 struct alc_spec *spec = codec->spec;
df694daa
KY
7250 alc882_auto_init_multi_out(codec);
7251 alc882_auto_init_hp_out(codec);
7252 alc882_auto_init_analog_input(codec);
f511b01c 7253 alc882_auto_init_input_src(codec);
f6c7e546 7254 if (spec->unsol_event)
7fb0d78f 7255 alc_inithook(codec);
df694daa
KY
7256}
7257
7943a8ab
TI
7258static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7259
df694daa
KY
7260static int patch_alc882(struct hda_codec *codec)
7261{
7262 struct alc_spec *spec;
7263 int err, board_config;
7264
7265 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7266 if (spec == NULL)
7267 return -ENOMEM;
7268
7269 codec->spec = spec;
7270
f5fcc13c
TI
7271 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7272 alc882_models,
7273 alc882_cfg_tbl);
df694daa
KY
7274
7275 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
7276 /* Pick up systems that don't supply PCI SSID */
7277 switch (codec->subsystem_id) {
7278 case 0x106b0c00: /* Mac Pro */
7279 board_config = ALC885_MACPRO;
7280 break;
c54728d8 7281 case 0x106b1000: /* iMac 24 */
f3911c5a 7282 case 0x106b2800: /* AppleTV */
3077e44c 7283 case 0x106b3e00: /* iMac 24 Aluminium */
c54728d8
NF
7284 board_config = ALC885_IMAC24;
7285 break;
2d466381 7286 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
c7e0757a 7287 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
9c95c43d 7288 case 0x106b00a4: /* MacbookPro4,1 */
87350ad0 7289 case 0x106b2c00: /* Macbook Pro rev3 */
c7e0757a 7290 case 0x106b3600: /* Macbook 3.1 */
2a88464c 7291 case 0x106b3800: /* MacbookPro4,1 - latter revision */
87350ad0
TI
7292 board_config = ALC885_MBP3;
7293 break;
41d5545d
KS
7294 case 0x106b3f00: /* Macbook 5,1 */
7295 board_config = ALC885_MB5;
7296 break;
081d17c4 7297 default:
7943a8ab 7298 /* ALC889A is handled better as ALC888-compatible */
669faba2
CM
7299 if (codec->revision_id == 0x100101 ||
7300 codec->revision_id == 0x100103) {
7943a8ab
TI
7301 alc_free(codec);
7302 return patch_alc883(codec);
7303 }
081d17c4
TD
7304 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7305 "trying auto-probe from BIOS...\n");
7306 board_config = ALC882_AUTO;
7307 }
df694daa
KY
7308 }
7309
f95474ec
TI
7310 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7311
df694daa
KY
7312 if (board_config == ALC882_AUTO) {
7313 /* automatic parse from the BIOS config */
7314 err = alc882_parse_auto_config(codec);
7315 if (err < 0) {
7316 alc_free(codec);
7317 return err;
f12ab1e0 7318 } else if (!err) {
9c7f852e
TI
7319 printk(KERN_INFO
7320 "hda_codec: Cannot set up configuration "
7321 "from BIOS. Using base mode...\n");
df694daa
KY
7322 board_config = ALC882_3ST_DIG;
7323 }
7324 }
7325
680cd536
KK
7326 err = snd_hda_attach_beep_device(codec, 0x1);
7327 if (err < 0) {
7328 alc_free(codec);
7329 return err;
7330 }
7331
df694daa
KY
7332 if (board_config != ALC882_AUTO)
7333 setup_preset(spec, &alc882_presets[board_config]);
1da177e4 7334
2f893286
KY
7335 if (codec->vendor_id == 0x10ec0885) {
7336 spec->stream_name_analog = "ALC885 Analog";
7337 spec->stream_name_digital = "ALC885 Digital";
7338 } else {
7339 spec->stream_name_analog = "ALC882 Analog";
7340 spec->stream_name_digital = "ALC882 Digital";
7341 }
7342
df694daa
KY
7343 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7344 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
7345 /* FIXME: setup DAC5 */
7346 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7347 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 7348
df694daa
KY
7349 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7350 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 7351
61b9b9b1 7352 spec->capture_style = CAPT_MIX; /* matrix-style capture */
f12ab1e0 7353 if (!spec->adc_nids && spec->input_mux) {
df694daa 7354 /* check whether NID 0x07 is valid */
4a471b7d 7355 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
7356 /* get type */
7357 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
7358 if (wcap != AC_WID_AUD_IN) {
7359 spec->adc_nids = alc882_adc_nids_alt;
7360 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 7361 spec->capsrc_nids = alc882_capsrc_nids_alt;
df694daa
KY
7362 } else {
7363 spec->adc_nids = alc882_adc_nids;
7364 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 7365 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
7366 }
7367 }
f9e336f6 7368 set_capture_mixer(spec);
45bdd1c1 7369 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 7370
2134ea4f
TI
7371 spec->vmaster_nid = 0x0c;
7372
1da177e4 7373 codec->patch_ops = alc_patch_ops;
df694daa 7374 if (board_config == ALC882_AUTO)
ae6b813a 7375 spec->init_hook = alc882_auto_init;
cb53c626
TI
7376#ifdef CONFIG_SND_HDA_POWER_SAVE
7377 if (!spec->loopback.amplist)
7378 spec->loopback.amplist = alc882_loopbacks;
7379#endif
daead538 7380 codec->proc_widget_hook = print_realtek_coef;
df694daa
KY
7381
7382 return 0;
7383}
7384
7385/*
9c7f852e
TI
7386 * ALC883 support
7387 *
7388 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7389 * configuration. Each pin widget can choose any input DACs and a mixer.
7390 * Each ADC is connected from a mixer of all inputs. This makes possible
7391 * 6-channel independent captures.
7392 *
7393 * In addition, an independent DAC for the multi-playback (not used in this
7394 * driver yet).
df694daa 7395 */
9c7f852e
TI
7396#define ALC883_DIGOUT_NID 0x06
7397#define ALC883_DIGIN_NID 0x0a
df694daa 7398
3ab90935
WF
7399#define ALC1200_DIGOUT_NID 0x10
7400
9c7f852e
TI
7401static hda_nid_t alc883_dac_nids[4] = {
7402 /* front, rear, clfe, rear_surr */
f32a19e3 7403 0x02, 0x03, 0x04, 0x05
9c7f852e 7404};
df694daa 7405
9c7f852e
TI
7406static hda_nid_t alc883_adc_nids[2] = {
7407 /* ADC1-2 */
7408 0x08, 0x09,
7409};
f12ab1e0 7410
f9e336f6
TI
7411static hda_nid_t alc883_adc_nids_alt[1] = {
7412 /* ADC1 */
7413 0x08,
7414};
7415
5b2d1eca
VP
7416static hda_nid_t alc883_adc_nids_rev[2] = {
7417 /* ADC2-1 */
7418 0x09, 0x08
7419};
7420
61b9b9b1
HRK
7421#define alc889_adc_nids alc880_adc_nids
7422
e1406348
TI
7423static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7424
5b2d1eca
VP
7425static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7426
61b9b9b1
HRK
7427#define alc889_capsrc_nids alc882_capsrc_nids
7428
9c7f852e
TI
7429/* input MUX */
7430/* FIXME: should be a matrix-type input source selection */
df694daa 7431
9c7f852e
TI
7432static struct hda_input_mux alc883_capture_source = {
7433 .num_items = 4,
7434 .items = {
7435 { "Mic", 0x0 },
7436 { "Front Mic", 0x1 },
7437 { "Line", 0x2 },
7438 { "CD", 0x4 },
7439 },
7440};
bc9f98a9 7441
17bba1b7
J
7442static struct hda_input_mux alc883_3stack_6ch_intel = {
7443 .num_items = 4,
7444 .items = {
7445 { "Mic", 0x1 },
7446 { "Front Mic", 0x0 },
7447 { "Line", 0x2 },
7448 { "CD", 0x4 },
7449 },
7450};
7451
bc9f98a9
KY
7452static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7453 .num_items = 2,
7454 .items = {
7455 { "Mic", 0x1 },
7456 { "Line", 0x2 },
7457 },
7458};
7459
272a527c
KY
7460static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7461 .num_items = 4,
7462 .items = {
7463 { "Mic", 0x0 },
7464 { "iMic", 0x1 },
7465 { "Line", 0x2 },
7466 { "CD", 0x4 },
7467 },
7468};
7469
fb97dc67
J
7470static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7471 .num_items = 2,
7472 .items = {
7473 { "Mic", 0x0 },
7474 { "Int Mic", 0x1 },
7475 },
7476};
7477
e2757d5e
KY
7478static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7479 .num_items = 3,
7480 .items = {
7481 { "Mic", 0x0 },
7482 { "Front Mic", 0x1 },
7483 { "Line", 0x4 },
7484 },
7485};
7486
7487static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7488 .num_items = 2,
7489 .items = {
7490 { "Mic", 0x0 },
7491 { "Line", 0x2 },
7492 },
7493};
7494
9c7f852e
TI
7495/*
7496 * 2ch mode
7497 */
7498static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7499 { 2, NULL }
7500};
7501
7502/*
7503 * 2ch mode
7504 */
7505static struct hda_verb alc883_3ST_ch2_init[] = {
7506 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7507 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7508 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7509 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7510 { } /* end */
7511};
7512
b201131c
TD
7513/*
7514 * 4ch mode
7515 */
7516static struct hda_verb alc883_3ST_ch4_init[] = {
7517 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7518 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7519 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7520 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7521 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7522 { } /* end */
7523};
7524
9c7f852e
TI
7525/*
7526 * 6ch mode
7527 */
7528static struct hda_verb alc883_3ST_ch6_init[] = {
7529 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7530 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7531 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7532 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7533 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7534 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7535 { } /* end */
7536};
7537
b201131c 7538static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 7539 { 2, alc883_3ST_ch2_init },
b201131c 7540 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
7541 { 6, alc883_3ST_ch6_init },
7542};
7543
17bba1b7
J
7544/*
7545 * 2ch mode
7546 */
7547static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7548 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7549 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7550 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7551 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7552 { } /* end */
7553};
7554
7555/*
7556 * 4ch mode
7557 */
7558static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7559 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7560 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7561 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7562 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7563 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7564 { } /* end */
7565};
7566
7567/*
7568 * 6ch mode
7569 */
7570static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7571 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7572 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7573 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7574 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7575 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7576 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7577 { } /* end */
7578};
7579
7580static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7581 { 2, alc883_3ST_ch2_intel_init },
7582 { 4, alc883_3ST_ch4_intel_init },
7583 { 6, alc883_3ST_ch6_intel_init },
7584};
7585
9c7f852e
TI
7586/*
7587 * 6ch mode
7588 */
7589static struct hda_verb alc883_sixstack_ch6_init[] = {
7590 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7591 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7592 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7593 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7594 { } /* end */
7595};
7596
7597/*
7598 * 8ch mode
7599 */
7600static struct hda_verb alc883_sixstack_ch8_init[] = {
7601 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7602 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7603 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7604 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7605 { } /* end */
7606};
7607
7608static struct hda_channel_mode alc883_sixstack_modes[2] = {
7609 { 6, alc883_sixstack_ch6_init },
7610 { 8, alc883_sixstack_ch8_init },
7611};
7612
b373bdeb
AN
7613static struct hda_verb alc883_medion_eapd_verbs[] = {
7614 /* eanable EAPD on medion laptop */
7615 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7616 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7617 { }
7618};
7619
9c7f852e
TI
7620/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7621 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7622 */
7623
7624static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 7625 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
7626 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7628 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7631 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7632 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7633 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7634 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
7636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7639 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7641 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 7642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 7643 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7644 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7645 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
df694daa 7646 { } /* end */
834be88d
TI
7647};
7648
a8848bd6
AS
7649static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7650 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7651 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7653 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7654 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7655 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7656 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7660 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7661 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7662 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
7663 { } /* end */
7664};
7665
0c4cc443 7666static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7667 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7668 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7674 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7676 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
7677 { } /* end */
7678};
7679
fb97dc67
J
7680static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7681 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7682 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7684 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7688 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7690 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
7691 { } /* end */
7692};
7693
9c7f852e
TI
7694static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7700 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7703 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7705 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7706 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7707 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7708 { } /* end */
7709};
df694daa 7710
9c7f852e
TI
7711static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7712 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7713 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7715 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7716 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7717 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7718 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7719 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7721 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7722 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7723 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7724 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7726 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7729 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7730 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7731 { } /* end */
7732};
7733
17bba1b7
J
7734static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7735 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7736 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7737 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7738 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7739 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7740 HDA_OUTPUT),
7741 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7742 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7743 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7745 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7746 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7747 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7748 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7749 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7750 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7751 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7752 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7753 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7754 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
7755 { } /* end */
7756};
7757
d1d985f0 7758static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7759 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7760 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7761 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7762 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7763 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7764 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7765 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7766 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7768 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7769 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7770 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7771 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7773 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7774 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7776 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 7777 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
7778 { } /* end */
7779};
7780
ccc656ce
KY
7781static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7782 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7783 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7784 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7785 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7786 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7787 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7788 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7789 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7790 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7791 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7792 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7794 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7796 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 7798 { } /* end */
f12ab1e0 7799};
ccc656ce
KY
7800
7801static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7802 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7804 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7805 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7806 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7807 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7808 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7809 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7810 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7811 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7812 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 7813 { } /* end */
f12ab1e0 7814};
ccc656ce 7815
bc9f98a9
KY
7816static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7817 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7818 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7819 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7820 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7822 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7823 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 7825 { } /* end */
f12ab1e0 7826};
bc9f98a9 7827
272a527c
KY
7828static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7829 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7830 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7832 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7833 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7836 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7837 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
7838 { } /* end */
7839};
7840
7841static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7842 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7844 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7845 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7846 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7848 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7850 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 7851 { } /* end */
ea1fb29a 7852};
272a527c 7853
2880a867 7854static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7856 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7857 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 7863 { } /* end */
d1a991a6 7864};
2880a867 7865
e2757d5e
KY
7866static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7869 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7870 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7871 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7872 0x0d, 1, 0x0, HDA_OUTPUT),
7873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7874 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7875 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7876 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7877 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
7878 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7879 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7880 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7881 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7883 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7886 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
7888 { } /* end */
7889};
7890
7891static struct hda_bind_ctls alc883_bind_cap_vol = {
7892 .ops = &snd_hda_bind_vol,
7893 .values = {
7894 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7895 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7896 0
7897 },
7898};
7899
7900static struct hda_bind_ctls alc883_bind_cap_switch = {
7901 .ops = &snd_hda_bind_sw,
7902 .values = {
7903 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7904 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7905 0
7906 },
7907};
7908
7909static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7913 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7914 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7916 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7917 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f9e336f6
TI
7918 { } /* end */
7919};
7920
7921static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
e2757d5e
KY
7922 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7923 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7924 {
7925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7926 /* .name = "Capture Source", */
7927 .name = "Input Source",
7928 .count = 1,
54cbc9ab
TI
7929 .info = alc_mux_enum_info,
7930 .get = alc_mux_enum_get,
7931 .put = alc_mux_enum_put,
e2757d5e
KY
7932 },
7933 { } /* end */
7934};
7935
9c7f852e
TI
7936static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7937 {
7938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7939 .name = "Channel Mode",
7940 .info = alc_ch_mode_info,
7941 .get = alc_ch_mode_get,
7942 .put = alc_ch_mode_put,
7943 },
7944 { } /* end */
7945};
7946
7947static struct hda_verb alc883_init_verbs[] = {
7948 /* ADC1: mute amp left and right */
e2757d5e 7949 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
df694daa 7950 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7951 /* ADC2: mute amp left and right */
7952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7953 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7954 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7955 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7956 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7958 /* Rear mixer */
7959 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7962 /* CLFE mixer */
7963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7965 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7966 /* Side mixer */
7967 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7968 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7969 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7970
cb53c626
TI
7971 /* mute analog input loopbacks */
7972 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7977
9c7f852e
TI
7978 /* Front Pin: output 0 (0x0c) */
7979 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7980 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7981 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7982 /* Rear Pin: output 1 (0x0d) */
7983 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7986 /* CLFE Pin: output 2 (0x0e) */
7987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7988 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7989 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7990 /* Side Pin: output 3 (0x0f) */
7991 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7993 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7994 /* Mic (rear) pin: input vref at 80% */
7995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7997 /* Front Mic pin: input vref at 80% */
7998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7999 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8000 /* Line In pin: input */
8001 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8003 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8004 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8005 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8006 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8007 /* CD pin widget for input */
8008 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8009
8010 /* FIXME: use matrix-type input source selection */
8011 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8012 /* Input mixer2 */
8013 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
8014 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8017 /* Input mixer3 */
8018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
8019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8022 { }
8023};
8024
a8848bd6 8025/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8026static void alc883_mitac_init_hook(struct hda_codec *codec)
a8848bd6 8027{
a9fd4f3f 8028 struct alc_spec *spec = codec->spec;
a8848bd6 8029
a9fd4f3f
TI
8030 spec->autocfg.hp_pins[0] = 0x15;
8031 spec->autocfg.speaker_pins[0] = 0x14;
8032 spec->autocfg.speaker_pins[1] = 0x17;
8033 alc_automute_amp(codec);
a8848bd6
AS
8034}
8035
8036/* auto-toggle front mic */
8037/*
8038static void alc883_mitac_mic_automute(struct hda_codec *codec)
8039{
8040 unsigned int present;
8041 unsigned char bits;
8042
8043 present = snd_hda_codec_read(codec, 0x18, 0,
8044 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8045 bits = present ? HDA_AMP_MUTE : 0;
8046 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8047}
8048*/
8049
a8848bd6
AS
8050static struct hda_verb alc883_mitac_verbs[] = {
8051 /* HP */
8052 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8054 /* Subwoofer */
8055 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8056 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8057
8058 /* enable unsolicited event */
8059 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8060 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8061
8062 { } /* end */
8063};
8064
0c4cc443 8065static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8066 /* HP */
8067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8068 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8069 /* Int speaker */
8070 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8072
8073 /* enable unsolicited event */
8074 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8075 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8076
8077 { } /* end */
8078};
8079
fb97dc67
J
8080static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8081 /* HP */
8082 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8084 /* Subwoofer */
8085 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8086 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8087
8088 /* enable unsolicited event */
8089 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8090
8091 { } /* end */
8092};
8093
ccc656ce
KY
8094static struct hda_verb alc883_tagra_verbs[] = {
8095 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8097
8098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8099 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8100
ccc656ce
KY
8101 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8102 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8104
8105 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
8106 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8107 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8108 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
8109
8110 { } /* end */
8111};
8112
bc9f98a9
KY
8113static struct hda_verb alc883_lenovo_101e_verbs[] = {
8114 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8115 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8116 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8117 { } /* end */
8118};
8119
272a527c
KY
8120static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8121 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8122 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8123 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8125 { } /* end */
8126};
8127
8128static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8130 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8131 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8132 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8133 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8134 { } /* end */
8135};
8136
189609ae
KY
8137static struct hda_verb alc883_haier_w66_verbs[] = {
8138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8140
8141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8142
8143 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8144 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8145 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8146 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8147 { } /* end */
8148};
8149
e2757d5e
KY
8150static struct hda_verb alc888_lenovo_sky_verbs[] = {
8151 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8153 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8154 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8155 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8156 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8157 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8159 { } /* end */
8160};
8161
8718b700
HRK
8162static struct hda_verb alc888_6st_dell_verbs[] = {
8163 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8164 { }
8165};
8166
a9fd4f3f 8167static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8718b700 8168{
a9fd4f3f 8169 struct alc_spec *spec = codec->spec;
8718b700 8170
a9fd4f3f
TI
8171 spec->autocfg.hp_pins[0] = 0x1b;
8172 spec->autocfg.speaker_pins[0] = 0x14;
8173 spec->autocfg.speaker_pins[1] = 0x16;
8174 spec->autocfg.speaker_pins[2] = 0x18;
8175 alc_automute_amp(codec);
8718b700
HRK
8176}
8177
4723c022 8178static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 8179 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
8180 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8181 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 8182 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 8183 { } /* end */
5795b9e6
CM
8184};
8185
3ea0d7cf
HRK
8186/*
8187 * 2ch mode
8188 */
4723c022 8189static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
8190 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8191 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8192 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8193 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 8194 { } /* end */
8341de60
CM
8195};
8196
3ea0d7cf
HRK
8197/*
8198 * 4ch mode
8199 */
8200static struct hda_verb alc888_3st_hp_4ch_init[] = {
8201 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8202 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8203 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8204 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8205 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8206 { } /* end */
8207};
8208
8209/*
8210 * 6ch mode
8211 */
4723c022 8212static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
8213 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8214 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 8215 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
8216 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8217 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
8218 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8219 { } /* end */
8341de60
CM
8220};
8221
3ea0d7cf 8222static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 8223 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 8224 { 4, alc888_3st_hp_4ch_init },
4723c022 8225 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
8226};
8227
272a527c
KY
8228/* toggle front-jack and RCA according to the hp-jack state */
8229static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8230{
8231 unsigned int present;
ea1fb29a 8232
272a527c
KY
8233 present = snd_hda_codec_read(codec, 0x1b, 0,
8234 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8235 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8236 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8237 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8238 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
8239}
8240
8241/* toggle RCA according to the front-jack state */
8242static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8243{
8244 unsigned int present;
ea1fb29a 8245
272a527c
KY
8246 present = snd_hda_codec_read(codec, 0x14, 0,
8247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8249 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 8250}
47fd830a 8251
272a527c
KY
8252static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8253 unsigned int res)
8254{
8255 if ((res >> 26) == ALC880_HP_EVENT)
8256 alc888_lenovo_ms7195_front_automute(codec);
8257 if ((res >> 26) == ALC880_FRONT_EVENT)
8258 alc888_lenovo_ms7195_rca_automute(codec);
8259}
8260
8261static struct hda_verb alc883_medion_md2_verbs[] = {
8262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8264
8265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8266
8267 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8268 { } /* end */
8269};
8270
8271/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8272static void alc883_medion_md2_init_hook(struct hda_codec *codec)
272a527c 8273{
a9fd4f3f 8274 struct alc_spec *spec = codec->spec;
272a527c 8275
a9fd4f3f
TI
8276 spec->autocfg.hp_pins[0] = 0x14;
8277 spec->autocfg.speaker_pins[0] = 0x15;
8278 alc_automute_amp(codec);
272a527c
KY
8279}
8280
ccc656ce 8281/* toggle speaker-output according to the hp-jack state */
a9fd4f3f
TI
8282#define alc883_tagra_init_hook alc882_targa_init_hook
8283#define alc883_tagra_unsol_event alc882_targa_unsol_event
368c7a95 8284
0c4cc443
HRK
8285static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8286{
8287 unsigned int present;
8288
8289 present = snd_hda_codec_read(codec, 0x18, 0,
8290 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8291 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8292 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8293}
8294
a9fd4f3f 8295static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
0c4cc443 8296{
a9fd4f3f
TI
8297 struct alc_spec *spec = codec->spec;
8298
8299 spec->autocfg.hp_pins[0] = 0x15;
8300 spec->autocfg.speaker_pins[0] = 0x14;
8301 alc_automute_amp(codec);
0c4cc443
HRK
8302 alc883_clevo_m720_mic_automute(codec);
8303}
8304
8305static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8306 unsigned int res)
8307{
0c4cc443 8308 switch (res >> 26) {
0c4cc443
HRK
8309 case ALC880_MIC_EVENT:
8310 alc883_clevo_m720_mic_automute(codec);
8311 break;
a9fd4f3f
TI
8312 default:
8313 alc_automute_amp_unsol_event(codec, res);
8314 break;
0c4cc443 8315 }
368c7a95
J
8316}
8317
fb97dc67 8318/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8319static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
fb97dc67 8320{
a9fd4f3f 8321 struct alc_spec *spec = codec->spec;
fb97dc67 8322
a9fd4f3f
TI
8323 spec->autocfg.hp_pins[0] = 0x14;
8324 spec->autocfg.speaker_pins[0] = 0x15;
8325 alc_automute_amp(codec);
fb97dc67
J
8326}
8327
a9fd4f3f 8328static void alc883_haier_w66_init_hook(struct hda_codec *codec)
fb97dc67 8329{
a9fd4f3f 8330 struct alc_spec *spec = codec->spec;
189609ae 8331
a9fd4f3f
TI
8332 spec->autocfg.hp_pins[0] = 0x1b;
8333 spec->autocfg.speaker_pins[0] = 0x14;
8334 alc_automute_amp(codec);
189609ae
KY
8335}
8336
bc9f98a9
KY
8337static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8338{
8339 unsigned int present;
f12ab1e0 8340 unsigned char bits;
bc9f98a9
KY
8341
8342 present = snd_hda_codec_read(codec, 0x14, 0,
8343 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8344 bits = present ? HDA_AMP_MUTE : 0;
8345 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8346 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8347}
8348
8349static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8350{
8351 unsigned int present;
f12ab1e0 8352 unsigned char bits;
bc9f98a9
KY
8353
8354 present = snd_hda_codec_read(codec, 0x1b, 0,
8355 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8356 bits = present ? HDA_AMP_MUTE : 0;
8357 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8358 HDA_AMP_MUTE, bits);
8359 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8360 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8361}
8362
8363static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8364 unsigned int res)
8365{
8366 if ((res >> 26) == ALC880_HP_EVENT)
8367 alc883_lenovo_101e_all_automute(codec);
8368 if ((res >> 26) == ALC880_FRONT_EVENT)
8369 alc883_lenovo_101e_ispeaker_automute(codec);
8370}
8371
676a9b53 8372/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8373static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
676a9b53 8374{
a9fd4f3f 8375 struct alc_spec *spec = codec->spec;
676a9b53 8376
a9fd4f3f
TI
8377 spec->autocfg.hp_pins[0] = 0x14;
8378 spec->autocfg.speaker_pins[0] = 0x15;
8379 spec->autocfg.speaker_pins[1] = 0x16;
8380 alc_automute_amp(codec);
676a9b53
TI
8381}
8382
d1a991a6
KY
8383static struct hda_verb alc883_acer_eapd_verbs[] = {
8384 /* HP Pin: output 0 (0x0c) */
8385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8386 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8387 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8388 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8389 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8392 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8393 /* eanable EAPD on medion laptop */
8394 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8395 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8396 /* enable unsolicited event */
8397 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8398 { }
8399};
8400
a9fd4f3f 8401static void alc888_6st_dell_init_hook(struct hda_codec *codec)
5795b9e6 8402{
a9fd4f3f 8403 struct alc_spec *spec = codec->spec;
5795b9e6 8404
a9fd4f3f
TI
8405 spec->autocfg.hp_pins[0] = 0x1b;
8406 spec->autocfg.speaker_pins[0] = 0x14;
8407 spec->autocfg.speaker_pins[1] = 0x15;
8408 spec->autocfg.speaker_pins[2] = 0x16;
8409 spec->autocfg.speaker_pins[3] = 0x17;
8410 alc_automute_amp(codec);
5795b9e6
CM
8411}
8412
a9fd4f3f 8413static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
e2757d5e 8414{
a9fd4f3f 8415 struct alc_spec *spec = codec->spec;
e2757d5e 8416
a9fd4f3f
TI
8417 spec->autocfg.hp_pins[0] = 0x1b;
8418 spec->autocfg.speaker_pins[0] = 0x14;
8419 spec->autocfg.speaker_pins[1] = 0x15;
8420 spec->autocfg.speaker_pins[2] = 0x16;
8421 spec->autocfg.speaker_pins[3] = 0x17;
8422 spec->autocfg.speaker_pins[4] = 0x1a;
8423 alc_automute_amp(codec);
e2757d5e
KY
8424}
8425
9c7f852e
TI
8426/*
8427 * generic initialization of ADC, input mixers and output mixers
8428 */
8429static struct hda_verb alc883_auto_init_verbs[] = {
8430 /*
8431 * Unmute ADC0-2 and set the default input to mic-in
8432 */
8433 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8436 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8437
cb53c626 8438 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8439 * mixer widget
f12ab1e0
TI
8440 * Note: PASD motherboards uses the Line In 2 as the input for
8441 * front panel mic (mic 2)
9c7f852e
TI
8442 */
8443 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8448 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8449
8450 /*
8451 * Set up output mixers (0x0c - 0x0f)
8452 */
8453 /* set vol=0 to output mixers */
8454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8455 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8457 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8458 /* set up input amps for analog loopback */
8459 /* Amp Indices: DAC = 0, mixer = 1 */
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8462 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8464 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8466 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8468 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8470
8471 /* FIXME: use matrix-type input source selection */
8472 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8473 /* Input mixer1 */
8474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8477 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
8478 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8479 /* Input mixer2 */
8480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8483 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 8484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
8485
8486 { }
8487};
8488
e2757d5e
KY
8489static struct hda_verb alc888_asus_m90v_verbs[] = {
8490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8491 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8493 /* enable unsolicited event */
8494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8495 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8496 { } /* end */
8497};
8498
8499static void alc883_nb_mic_automute(struct hda_codec *codec)
8500{
8501 unsigned int present;
8502
8503 present = snd_hda_codec_read(codec, 0x18, 0,
8504 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8505 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8506 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8507 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8508 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8509}
8510
a9fd4f3f 8511static void alc883_M90V_init_hook(struct hda_codec *codec)
e2757d5e 8512{
a9fd4f3f 8513 struct alc_spec *spec = codec->spec;
e2757d5e 8514
a9fd4f3f
TI
8515 spec->autocfg.hp_pins[0] = 0x1b;
8516 spec->autocfg.speaker_pins[0] = 0x14;
8517 spec->autocfg.speaker_pins[1] = 0x15;
8518 spec->autocfg.speaker_pins[2] = 0x16;
8519 alc_automute_pin(codec);
e2757d5e
KY
8520}
8521
8522static void alc883_mode2_unsol_event(struct hda_codec *codec,
8523 unsigned int res)
8524{
8525 switch (res >> 26) {
e2757d5e
KY
8526 case ALC880_MIC_EVENT:
8527 alc883_nb_mic_automute(codec);
8528 break;
a9fd4f3f
TI
8529 default:
8530 alc_sku_unsol_event(codec, res);
8531 break;
e2757d5e
KY
8532 }
8533}
8534
8535static void alc883_mode2_inithook(struct hda_codec *codec)
8536{
a9fd4f3f 8537 alc883_M90V_init_hook(codec);
e2757d5e
KY
8538 alc883_nb_mic_automute(codec);
8539}
8540
8541static struct hda_verb alc888_asus_eee1601_verbs[] = {
8542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8547 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8548 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8549 /* enable unsolicited event */
8550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8551 { } /* end */
8552};
8553
e2757d5e
KY
8554static void alc883_eee1601_inithook(struct hda_codec *codec)
8555{
a9fd4f3f
TI
8556 struct alc_spec *spec = codec->spec;
8557
8558 spec->autocfg.hp_pins[0] = 0x14;
8559 spec->autocfg.speaker_pins[0] = 0x1b;
8560 alc_automute_pin(codec);
e2757d5e
KY
8561}
8562
cb53c626
TI
8563#ifdef CONFIG_SND_HDA_POWER_SAVE
8564#define alc883_loopbacks alc880_loopbacks
8565#endif
8566
9c7f852e
TI
8567/* pcm configuration: identiacal with ALC880 */
8568#define alc883_pcm_analog_playback alc880_pcm_analog_playback
8569#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 8570#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
8571#define alc883_pcm_digital_playback alc880_pcm_digital_playback
8572#define alc883_pcm_digital_capture alc880_pcm_digital_capture
8573
8574/*
8575 * configuration and preset
8576 */
f5fcc13c
TI
8577static const char *alc883_models[ALC883_MODEL_LAST] = {
8578 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8579 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8580 [ALC883_3ST_6ch] = "3stack-6ch",
8581 [ALC883_6ST_DIG] = "6stack-dig",
8582 [ALC883_TARGA_DIG] = "targa-dig",
8583 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 8584 [ALC883_ACER] = "acer",
2880a867 8585 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 8586 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
f5fcc13c 8587 [ALC883_MEDION] = "medion",
272a527c 8588 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8589 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8590 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8591 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8592 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8593 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8594 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8595 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8596 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8597 [ALC883_MITAC] = "mitac",
0c4cc443 8598 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8599 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 8600 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 8601 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
3ab90935 8602 [ALC1200_ASUS_P5Q] = "asus-p5q",
f5fcc13c
TI
8603 [ALC883_AUTO] = "auto",
8604};
8605
8606static struct snd_pci_quirk alc883_cfg_tbl[] = {
8607 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741 8608 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 8609 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 8610 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
8611 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8612 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8613 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
8614 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8615 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd
LW
8616 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8617 ALC888_ACER_ASPIRE_4930G),
b3bdb30b 8618 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
94683507 8619 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
a8e4f9dd
LW
8620 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8621 ALC888_ACER_ASPIRE_4930G),
cc374c47
JJGS
8622 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8623 ALC888_ACER_ASPIRE_4930G),
dea0a509
TI
8624 /* default Acer */
8625 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
5795b9e6 8626 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 8627 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8628 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8629 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8630 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 8631 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 8632 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
a01c30cb 8633 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
ac3e3741 8634 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 8635 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 8636 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 8637 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
97ec710c 8638 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 8639 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
2de686d2 8640 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
8641 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8642 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8643 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8644 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 8645 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 8646 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8647 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8648 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 8649 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 8650 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8651 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8652 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8653 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8654 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8655 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8656 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8657 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8658 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8659 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8660 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
8661 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8662 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8663 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 8664 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 8665 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8666 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8667 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 8668 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8669 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8670 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8671 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
dea0a509 8672 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8673 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 8674 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 8675 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 8676 ALC883_FUJITSU_PI2515),
bfb53037 8677 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 8678 ALC888_FUJITSU_XA3530),
272a527c 8679 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8680 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8681 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8682 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8683 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8684 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 8685 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 8686 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8687 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
17bba1b7
J
8688 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8689 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 8690 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
4b558991 8691 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
ac3e3741 8692 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
8693 {}
8694};
8695
f3cd3f5d
WF
8696static hda_nid_t alc883_slave_dig_outs[] = {
8697 ALC1200_DIGOUT_NID, 0,
8698};
8699
b25c9da1
WF
8700static hda_nid_t alc1200_slave_dig_outs[] = {
8701 ALC883_DIGOUT_NID, 0,
8702};
8703
9c7f852e
TI
8704static struct alc_config_preset alc883_presets[] = {
8705 [ALC883_3ST_2ch_DIG] = {
8706 .mixers = { alc883_3ST_2ch_mixer },
8707 .init_verbs = { alc883_init_verbs },
8708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8709 .dac_nids = alc883_dac_nids,
8710 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8711 .dig_in_nid = ALC883_DIGIN_NID,
8712 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8713 .channel_mode = alc883_3ST_2ch_modes,
8714 .input_mux = &alc883_capture_source,
8715 },
8716 [ALC883_3ST_6ch_DIG] = {
8717 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8718 .init_verbs = { alc883_init_verbs },
8719 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8720 .dac_nids = alc883_dac_nids,
8721 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8722 .dig_in_nid = ALC883_DIGIN_NID,
8723 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8724 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8725 .need_dac_fix = 1,
9c7f852e 8726 .input_mux = &alc883_capture_source,
f12ab1e0 8727 },
9c7f852e
TI
8728 [ALC883_3ST_6ch] = {
8729 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8730 .init_verbs = { alc883_init_verbs },
8731 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8732 .dac_nids = alc883_dac_nids,
9c7f852e
TI
8733 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8734 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8735 .need_dac_fix = 1,
9c7f852e 8736 .input_mux = &alc883_capture_source,
f12ab1e0 8737 },
17bba1b7
J
8738 [ALC883_3ST_6ch_INTEL] = {
8739 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8740 .init_verbs = { alc883_init_verbs },
8741 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8742 .dac_nids = alc883_dac_nids,
8743 .dig_out_nid = ALC883_DIGOUT_NID,
8744 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 8745 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
8746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8747 .channel_mode = alc883_3ST_6ch_intel_modes,
8748 .need_dac_fix = 1,
8749 .input_mux = &alc883_3stack_6ch_intel,
8750 },
9c7f852e
TI
8751 [ALC883_6ST_DIG] = {
8752 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8753 .init_verbs = { alc883_init_verbs },
8754 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8755 .dac_nids = alc883_dac_nids,
8756 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8757 .dig_in_nid = ALC883_DIGIN_NID,
8758 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8759 .channel_mode = alc883_sixstack_modes,
8760 .input_mux = &alc883_capture_source,
8761 },
ccc656ce
KY
8762 [ALC883_TARGA_DIG] = {
8763 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8764 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8765 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8766 .dac_nids = alc883_dac_nids,
8767 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8768 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8769 .channel_mode = alc883_3ST_6ch_modes,
8770 .need_dac_fix = 1,
8771 .input_mux = &alc883_capture_source,
8772 .unsol_event = alc883_tagra_unsol_event,
a9fd4f3f 8773 .init_hook = alc883_tagra_init_hook,
ccc656ce
KY
8774 },
8775 [ALC883_TARGA_2ch_DIG] = {
8776 .mixers = { alc883_tagra_2ch_mixer},
8777 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8778 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8779 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8780 .adc_nids = alc883_adc_nids_alt,
8781 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
ccc656ce 8782 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8783 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8784 .channel_mode = alc883_3ST_2ch_modes,
8785 .input_mux = &alc883_capture_source,
8786 .unsol_event = alc883_tagra_unsol_event,
a9fd4f3f 8787 .init_hook = alc883_tagra_init_hook,
ccc656ce 8788 },
bab282b9 8789 [ALC883_ACER] = {
676a9b53 8790 .mixers = { alc883_base_mixer },
bab282b9
VA
8791 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8792 * and the headphone jack. Turn this on and rely on the
8793 * standard mute methods whenever the user wants to turn
8794 * these outputs off.
8795 */
8796 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8797 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8798 .dac_nids = alc883_dac_nids,
bab282b9
VA
8799 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8800 .channel_mode = alc883_3ST_2ch_modes,
8801 .input_mux = &alc883_capture_source,
8802 },
2880a867 8803 [ALC883_ACER_ASPIRE] = {
676a9b53 8804 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 8805 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
8806 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8807 .dac_nids = alc883_dac_nids,
8808 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
8809 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8810 .channel_mode = alc883_3ST_2ch_modes,
8811 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8812 .unsol_event = alc_automute_amp_unsol_event,
8813 .init_hook = alc883_acer_aspire_init_hook,
d1a991a6 8814 },
5b2d1eca 8815 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 8816 .mixers = { alc888_base_mixer,
5b2d1eca
VP
8817 alc883_chmode_mixer },
8818 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8819 alc888_acer_aspire_4930g_verbs },
8820 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8821 .dac_nids = alc883_dac_nids,
8822 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8823 .adc_nids = alc883_adc_nids_rev,
8824 .capsrc_nids = alc883_capsrc_nids_rev,
8825 .dig_out_nid = ALC883_DIGOUT_NID,
8826 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8827 .channel_mode = alc883_3ST_6ch_modes,
8828 .need_dac_fix = 1,
8829 .num_mux_defs =
ef8ef5fb
VP
8830 ARRAY_SIZE(alc888_2_capture_sources),
8831 .input_mux = alc888_2_capture_sources,
a9fd4f3f
TI
8832 .unsol_event = alc_automute_amp_unsol_event,
8833 .init_hook = alc888_acer_aspire_4930g_init_hook,
5b2d1eca 8834 },
c07584c8
TD
8835 [ALC883_MEDION] = {
8836 .mixers = { alc883_fivestack_mixer,
8837 alc883_chmode_mixer },
8838 .init_verbs = { alc883_init_verbs,
b373bdeb 8839 alc883_medion_eapd_verbs },
c07584c8
TD
8840 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8841 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8842 .adc_nids = alc883_adc_nids_alt,
8843 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
c07584c8
TD
8844 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8845 .channel_mode = alc883_sixstack_modes,
8846 .input_mux = &alc883_capture_source,
b373bdeb 8847 },
272a527c
KY
8848 [ALC883_MEDION_MD2] = {
8849 .mixers = { alc883_medion_md2_mixer},
8850 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8851 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8852 .dac_nids = alc883_dac_nids,
8853 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8854 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8855 .channel_mode = alc883_3ST_2ch_modes,
8856 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8857 .unsol_event = alc_automute_amp_unsol_event,
8858 .init_hook = alc883_medion_md2_init_hook,
ea1fb29a 8859 },
b373bdeb 8860 [ALC883_LAPTOP_EAPD] = {
676a9b53 8861 .mixers = { alc883_base_mixer },
b373bdeb
AN
8862 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8863 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8864 .dac_nids = alc883_dac_nids,
b373bdeb
AN
8865 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8866 .channel_mode = alc883_3ST_2ch_modes,
8867 .input_mux = &alc883_capture_source,
8868 },
0c4cc443
HRK
8869 [ALC883_CLEVO_M720] = {
8870 .mixers = { alc883_clevo_m720_mixer },
8871 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
8872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8873 .dac_nids = alc883_dac_nids,
8874 .dig_out_nid = ALC883_DIGOUT_NID,
8875 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8876 .channel_mode = alc883_3ST_2ch_modes,
8877 .input_mux = &alc883_capture_source,
0c4cc443 8878 .unsol_event = alc883_clevo_m720_unsol_event,
a9fd4f3f 8879 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 8880 },
bc9f98a9
KY
8881 [ALC883_LENOVO_101E_2ch] = {
8882 .mixers = { alc883_lenovo_101e_2ch_mixer},
8883 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8884 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8885 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8886 .adc_nids = alc883_adc_nids_alt,
8887 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
bc9f98a9
KY
8888 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8889 .channel_mode = alc883_3ST_2ch_modes,
8890 .input_mux = &alc883_lenovo_101e_capture_source,
8891 .unsol_event = alc883_lenovo_101e_unsol_event,
8892 .init_hook = alc883_lenovo_101e_all_automute,
8893 },
272a527c
KY
8894 [ALC883_LENOVO_NB0763] = {
8895 .mixers = { alc883_lenovo_nb0763_mixer },
8896 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8897 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8898 .dac_nids = alc883_dac_nids,
272a527c
KY
8899 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8900 .channel_mode = alc883_3ST_2ch_modes,
8901 .need_dac_fix = 1,
8902 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f
TI
8903 .unsol_event = alc_automute_amp_unsol_event,
8904 .init_hook = alc883_medion_md2_init_hook,
272a527c
KY
8905 },
8906 [ALC888_LENOVO_MS7195_DIG] = {
8907 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8908 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8909 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8910 .dac_nids = alc883_dac_nids,
8911 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8912 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8913 .channel_mode = alc883_3ST_6ch_modes,
8914 .need_dac_fix = 1,
8915 .input_mux = &alc883_capture_source,
8916 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8917 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
8918 },
8919 [ALC883_HAIER_W66] = {
8920 .mixers = { alc883_tagra_2ch_mixer},
8921 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8922 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8923 .dac_nids = alc883_dac_nids,
8924 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
8925 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8926 .channel_mode = alc883_3ST_2ch_modes,
8927 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8928 .unsol_event = alc_automute_amp_unsol_event,
8929 .init_hook = alc883_haier_w66_init_hook,
eea6419e 8930 },
4723c022 8931 [ALC888_3ST_HP] = {
eea6419e 8932 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 8933 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
8934 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8935 .dac_nids = alc883_dac_nids,
4723c022
CM
8936 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8937 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
8938 .need_dac_fix = 1,
8939 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8940 .unsol_event = alc_automute_amp_unsol_event,
8941 .init_hook = alc888_3st_hp_init_hook,
8341de60 8942 },
5795b9e6 8943 [ALC888_6ST_DELL] = {
f24dbdc6 8944 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
8945 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8946 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8947 .dac_nids = alc883_dac_nids,
8948 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
8949 .dig_in_nid = ALC883_DIGIN_NID,
8950 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8951 .channel_mode = alc883_sixstack_modes,
8952 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8953 .unsol_event = alc_automute_amp_unsol_event,
8954 .init_hook = alc888_6st_dell_init_hook,
5795b9e6 8955 },
a8848bd6
AS
8956 [ALC883_MITAC] = {
8957 .mixers = { alc883_mitac_mixer },
8958 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8959 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8960 .dac_nids = alc883_dac_nids,
a8848bd6
AS
8961 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8962 .channel_mode = alc883_3ST_2ch_modes,
8963 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8964 .unsol_event = alc_automute_amp_unsol_event,
8965 .init_hook = alc883_mitac_init_hook,
a8848bd6 8966 },
fb97dc67
J
8967 [ALC883_FUJITSU_PI2515] = {
8968 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8969 .init_verbs = { alc883_init_verbs,
8970 alc883_2ch_fujitsu_pi2515_verbs},
8971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8972 .dac_nids = alc883_dac_nids,
8973 .dig_out_nid = ALC883_DIGOUT_NID,
8974 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8975 .channel_mode = alc883_3ST_2ch_modes,
8976 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f
TI
8977 .unsol_event = alc_automute_amp_unsol_event,
8978 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
fb97dc67 8979 },
ef8ef5fb
VP
8980 [ALC888_FUJITSU_XA3530] = {
8981 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8982 .init_verbs = { alc883_init_verbs,
8983 alc888_fujitsu_xa3530_verbs },
8984 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8985 .dac_nids = alc883_dac_nids,
8986 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8987 .adc_nids = alc883_adc_nids_rev,
8988 .capsrc_nids = alc883_capsrc_nids_rev,
8989 .dig_out_nid = ALC883_DIGOUT_NID,
8990 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8991 .channel_mode = alc888_4ST_8ch_intel_modes,
8992 .num_mux_defs =
8993 ARRAY_SIZE(alc888_2_capture_sources),
8994 .input_mux = alc888_2_capture_sources,
a9fd4f3f
TI
8995 .unsol_event = alc_automute_amp_unsol_event,
8996 .init_hook = alc888_fujitsu_xa3530_init_hook,
ef8ef5fb 8997 },
e2757d5e
KY
8998 [ALC888_LENOVO_SKY] = {
8999 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9000 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9001 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9002 .dac_nids = alc883_dac_nids,
9003 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
9004 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9005 .channel_mode = alc883_sixstack_modes,
9006 .need_dac_fix = 1,
9007 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f
TI
9008 .unsol_event = alc_automute_amp_unsol_event,
9009 .init_hook = alc888_lenovo_sky_init_hook,
e2757d5e
KY
9010 },
9011 [ALC888_ASUS_M90V] = {
9012 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9013 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9014 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9015 .dac_nids = alc883_dac_nids,
9016 .dig_out_nid = ALC883_DIGOUT_NID,
9017 .dig_in_nid = ALC883_DIGIN_NID,
9018 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9019 .channel_mode = alc883_3ST_6ch_modes,
9020 .need_dac_fix = 1,
9021 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9022 .unsol_event = alc883_mode2_unsol_event,
9023 .init_hook = alc883_mode2_inithook,
9024 },
9025 [ALC888_ASUS_EEE1601] = {
9026 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 9027 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
9028 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9029 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9030 .dac_nids = alc883_dac_nids,
9031 .dig_out_nid = ALC883_DIGOUT_NID,
9032 .dig_in_nid = ALC883_DIGIN_NID,
9033 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9034 .channel_mode = alc883_3ST_2ch_modes,
9035 .need_dac_fix = 1,
9036 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 9037 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
9038 .init_hook = alc883_eee1601_inithook,
9039 },
3ab90935
WF
9040 [ALC1200_ASUS_P5Q] = {
9041 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9042 .init_verbs = { alc883_init_verbs },
9043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9044 .dac_nids = alc883_dac_nids,
9045 .dig_out_nid = ALC1200_DIGOUT_NID,
9046 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 9047 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
9048 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9049 .channel_mode = alc883_sixstack_modes,
9050 .input_mux = &alc883_capture_source,
9051 },
9c7f852e
TI
9052};
9053
9054
9055/*
9056 * BIOS auto configuration
9057 */
9058static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9059 hda_nid_t nid, int pin_type,
9060 int dac_idx)
9061{
9062 /* set as output */
9063 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
9064 int idx;
9065
f6c7e546 9066 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
9067 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9068 idx = 4;
9069 else
9070 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
9071 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9072
9073}
9074
9075static void alc883_auto_init_multi_out(struct hda_codec *codec)
9076{
9077 struct alc_spec *spec = codec->spec;
9078 int i;
9079
9080 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 9081 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 9082 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 9083 if (nid)
baba8ee9 9084 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 9085 i);
9c7f852e
TI
9086 }
9087}
9088
9089static void alc883_auto_init_hp_out(struct hda_codec *codec)
9090{
9091 struct alc_spec *spec = codec->spec;
9092 hda_nid_t pin;
9093
eb06ed8f 9094 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
9095 if (pin) /* connect to front */
9096 /* use dac 0 */
9097 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
9098 pin = spec->autocfg.speaker_pins[0];
9099 if (pin)
9100 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
9101}
9102
9103#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9104#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9105
9106static void alc883_auto_init_analog_input(struct hda_codec *codec)
9107{
9108 struct alc_spec *spec = codec->spec;
9109 int i;
9110
9111 for (i = 0; i < AUTO_PIN_LAST; i++) {
9112 hda_nid_t nid = spec->autocfg.input_pins[i];
9113 if (alc883_is_input_pin(nid)) {
23f0c048 9114 alc_set_input_pin(codec, nid, i);
e82c025b
TI
9115 if (nid != ALC883_PIN_CD_NID &&
9116 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9c7f852e
TI
9117 snd_hda_codec_write(codec, nid, 0,
9118 AC_VERB_SET_AMP_GAIN_MUTE,
9119 AMP_OUT_MUTE);
9120 }
9121 }
9122}
9123
f511b01c
TI
9124#define alc883_auto_init_input_src alc882_auto_init_input_src
9125
9c7f852e
TI
9126/* almost identical with ALC880 parser... */
9127static int alc883_parse_auto_config(struct hda_codec *codec)
9128{
9129 struct alc_spec *spec = codec->spec;
9130 int err = alc880_parse_auto_config(codec);
61b9b9b1
HRK
9131 struct auto_pin_cfg *cfg = &spec->autocfg;
9132 int i;
9c7f852e
TI
9133
9134 if (err < 0)
9135 return err;
776e184e
TI
9136 else if (!err)
9137 return 0; /* no config found */
9138
9139 err = alc_auto_add_mic_boost(codec);
9140 if (err < 0)
9141 return err;
9142
9143 /* hack - override the init verbs */
9144 spec->init_verbs[0] = alc883_auto_init_verbs;
776e184e 9145
61b9b9b1
HRK
9146 /* setup input_mux for ALC889 */
9147 if (codec->vendor_id == 0x10ec0889) {
9148 /* digital-mic input pin is excluded in alc880_auto_create..()
9149 * because it's under 0x18
9150 */
9151 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9152 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9153 struct hda_input_mux *imux = &spec->private_imux[0];
9154 for (i = 1; i < 3; i++)
9155 memcpy(&spec->private_imux[i],
9156 &spec->private_imux[0],
9157 sizeof(spec->private_imux[0]));
9158 imux->items[imux->num_items].label = "Int DMic";
9159 imux->items[imux->num_items].index = 0x0b;
9160 imux->num_items++;
9161 spec->num_mux_defs = 3;
9162 spec->input_mux = spec->private_imux;
9163 }
9164 }
9165
776e184e 9166 return 1; /* config found */
9c7f852e
TI
9167}
9168
9169/* additional initialization for auto-configuration model */
9170static void alc883_auto_init(struct hda_codec *codec)
9171{
f6c7e546 9172 struct alc_spec *spec = codec->spec;
9c7f852e
TI
9173 alc883_auto_init_multi_out(codec);
9174 alc883_auto_init_hp_out(codec);
9175 alc883_auto_init_analog_input(codec);
f511b01c 9176 alc883_auto_init_input_src(codec);
f6c7e546 9177 if (spec->unsol_event)
7fb0d78f 9178 alc_inithook(codec);
9c7f852e
TI
9179}
9180
9181static int patch_alc883(struct hda_codec *codec)
9182{
9183 struct alc_spec *spec;
9184 int err, board_config;
9185
9186 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9187 if (spec == NULL)
9188 return -ENOMEM;
9189
9190 codec->spec = spec;
9191
2c3bf9ab
TI
9192 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9193
f5fcc13c
TI
9194 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9195 alc883_models,
9196 alc883_cfg_tbl);
9197 if (board_config < 0) {
9c7f852e
TI
9198 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9199 "trying auto-probe from BIOS...\n");
9200 board_config = ALC883_AUTO;
9201 }
9202
9203 if (board_config == ALC883_AUTO) {
9204 /* automatic parse from the BIOS config */
9205 err = alc883_parse_auto_config(codec);
9206 if (err < 0) {
9207 alc_free(codec);
9208 return err;
f12ab1e0 9209 } else if (!err) {
9c7f852e
TI
9210 printk(KERN_INFO
9211 "hda_codec: Cannot set up configuration "
9212 "from BIOS. Using base mode...\n");
9213 board_config = ALC883_3ST_2ch_DIG;
9214 }
9215 }
9216
680cd536
KK
9217 err = snd_hda_attach_beep_device(codec, 0x1);
9218 if (err < 0) {
9219 alc_free(codec);
9220 return err;
9221 }
9222
9c7f852e
TI
9223 if (board_config != ALC883_AUTO)
9224 setup_preset(spec, &alc883_presets[board_config]);
9225
2f893286
KY
9226 switch (codec->vendor_id) {
9227 case 0x10ec0888:
4442608d
KY
9228 if (codec->revision_id == 0x100101) {
9229 spec->stream_name_analog = "ALC1200 Analog";
9230 spec->stream_name_digital = "ALC1200 Digital";
9231 } else {
9232 spec->stream_name_analog = "ALC888 Analog";
9233 spec->stream_name_digital = "ALC888 Digital";
9234 }
61b9b9b1
HRK
9235 if (!spec->num_adc_nids) {
9236 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9237 spec->adc_nids = alc883_adc_nids;
9238 }
9239 if (!spec->capsrc_nids)
9240 spec->capsrc_nids = alc883_capsrc_nids;
9241 spec->capture_style = CAPT_MIX; /* matrix-style capture */
4a79ba34 9242 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
2f893286
KY
9243 break;
9244 case 0x10ec0889:
9245 spec->stream_name_analog = "ALC889 Analog";
9246 spec->stream_name_digital = "ALC889 Digital";
61b9b9b1
HRK
9247 if (!spec->num_adc_nids) {
9248 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9249 spec->adc_nids = alc889_adc_nids;
9250 }
9251 if (!spec->capsrc_nids)
9252 spec->capsrc_nids = alc889_capsrc_nids;
9253 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9254 capture */
2f893286
KY
9255 break;
9256 default:
9257 spec->stream_name_analog = "ALC883 Analog";
9258 spec->stream_name_digital = "ALC883 Digital";
61b9b9b1
HRK
9259 if (!spec->num_adc_nids) {
9260 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9261 spec->adc_nids = alc883_adc_nids;
9262 }
9263 if (!spec->capsrc_nids)
9264 spec->capsrc_nids = alc883_capsrc_nids;
9265 spec->capture_style = CAPT_MIX; /* matrix-style capture */
2f893286
KY
9266 break;
9267 }
9268
9c7f852e
TI
9269 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9270 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 9271 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e 9272
9c7f852e
TI
9273 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9274 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9275
f9e336f6
TI
9276 if (!spec->cap_mixer)
9277 set_capture_mixer(spec);
45bdd1c1 9278 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 9279
2134ea4f
TI
9280 spec->vmaster_nid = 0x0c;
9281
9c7f852e
TI
9282 codec->patch_ops = alc_patch_ops;
9283 if (board_config == ALC883_AUTO)
9284 spec->init_hook = alc883_auto_init;
f9423e7a 9285
cb53c626
TI
9286#ifdef CONFIG_SND_HDA_POWER_SAVE
9287 if (!spec->loopback.amplist)
9288 spec->loopback.amplist = alc883_loopbacks;
9289#endif
daead538 9290 codec->proc_widget_hook = print_realtek_coef;
9c7f852e
TI
9291
9292 return 0;
9293}
9294
9295/*
9296 * ALC262 support
9297 */
9298
9299#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9300#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9301
9302#define alc262_dac_nids alc260_dac_nids
9303#define alc262_adc_nids alc882_adc_nids
9304#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
9305#define alc262_capsrc_nids alc882_capsrc_nids
9306#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
9307
9308#define alc262_modes alc260_modes
9309#define alc262_capture_source alc882_capture_source
9310
4e555fe5
KY
9311static hda_nid_t alc262_dmic_adc_nids[1] = {
9312 /* ADC0 */
9313 0x09
9314};
9315
9316static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9317
9c7f852e
TI
9318static struct snd_kcontrol_new alc262_base_mixer[] = {
9319 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9320 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9321 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9322 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9323 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9324 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9327 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9328 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9329 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9330 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9333 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9334 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9335 { } /* end */
9336};
9337
ce875f07
TI
9338/* update HP, line and mono-out pins according to the master switch */
9339static void alc262_hp_master_update(struct hda_codec *codec)
9340{
9341 struct alc_spec *spec = codec->spec;
9342 int val = spec->master_sw;
9343
9344 /* HP & line-out */
9345 snd_hda_codec_write_cache(codec, 0x1b, 0,
9346 AC_VERB_SET_PIN_WIDGET_CONTROL,
9347 val ? PIN_HP : 0);
9348 snd_hda_codec_write_cache(codec, 0x15, 0,
9349 AC_VERB_SET_PIN_WIDGET_CONTROL,
9350 val ? PIN_HP : 0);
9351 /* mono (speaker) depending on the HP jack sense */
9352 val = val && !spec->jack_present;
9353 snd_hda_codec_write_cache(codec, 0x16, 0,
9354 AC_VERB_SET_PIN_WIDGET_CONTROL,
9355 val ? PIN_OUT : 0);
9356}
9357
9358static void alc262_hp_bpc_automute(struct hda_codec *codec)
9359{
9360 struct alc_spec *spec = codec->spec;
9361 unsigned int presence;
9362 presence = snd_hda_codec_read(codec, 0x1b, 0,
9363 AC_VERB_GET_PIN_SENSE, 0);
9364 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9365 alc262_hp_master_update(codec);
9366}
9367
9368static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9369{
9370 if ((res >> 26) != ALC880_HP_EVENT)
9371 return;
9372 alc262_hp_bpc_automute(codec);
9373}
9374
9375static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9376{
9377 struct alc_spec *spec = codec->spec;
9378 unsigned int presence;
9379 presence = snd_hda_codec_read(codec, 0x15, 0,
9380 AC_VERB_GET_PIN_SENSE, 0);
9381 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9382 alc262_hp_master_update(codec);
9383}
9384
9385static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9386 unsigned int res)
9387{
9388 if ((res >> 26) != ALC880_HP_EVENT)
9389 return;
9390 alc262_hp_wildwest_automute(codec);
9391}
9392
b72519b5 9393#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
9394
9395static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9396 struct snd_ctl_elem_value *ucontrol)
9397{
9398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9399 struct alc_spec *spec = codec->spec;
9400 int val = !!*ucontrol->value.integer.value;
9401
9402 if (val == spec->master_sw)
9403 return 0;
9404 spec->master_sw = val;
9405 alc262_hp_master_update(codec);
9406 return 1;
9407}
9408
b72519b5
TI
9409#define ALC262_HP_MASTER_SWITCH \
9410 { \
9411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9412 .name = "Master Playback Switch", \
9413 .info = snd_ctl_boolean_mono_info, \
9414 .get = alc262_hp_master_sw_get, \
9415 .put = alc262_hp_master_sw_put, \
9416 }
9417
9c7f852e 9418static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 9419 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
9420 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9421 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9423 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9424 HDA_OUTPUT),
9425 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9426 HDA_OUTPUT),
9c7f852e
TI
9427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9429 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9430 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9431 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9432 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9433 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9434 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
9437 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9438 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9439 { } /* end */
9440};
9441
cd7509a4 9442static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 9443 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
9444 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9445 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9446 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9448 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9449 HDA_OUTPUT),
9450 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9451 HDA_OUTPUT),
cd7509a4
KY
9452 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9453 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9454 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9457 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9458 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
9459 { } /* end */
9460};
9461
9462static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9463 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9464 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9465 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9466 { } /* end */
9467};
9468
66d2a9d6 9469/* mute/unmute internal speaker according to the hp jack and mute state */
a9fd4f3f 9470static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
66d2a9d6
KY
9471{
9472 struct alc_spec *spec = codec->spec;
66d2a9d6 9473
a9fd4f3f
TI
9474 spec->autocfg.hp_pins[0] = 0x15;
9475 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9476 alc_automute_amp(codec);
66d2a9d6
KY
9477}
9478
66d2a9d6 9479static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9480 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9481 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9482 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9486 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9487 { } /* end */
9488};
9489
9490static struct hda_verb alc262_hp_t5735_verbs[] = {
9491 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9493
9494 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9495 { }
9496};
9497
8c427226 9498static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9499 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9501 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9502 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9505 { } /* end */
9506};
9507
9508static struct hda_verb alc262_hp_rp5700_verbs[] = {
9509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9510 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9511 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9512 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9513 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9514 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9519 {}
9520};
9521
9522static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9523 .num_items = 1,
9524 .items = {
9525 { "Line", 0x1 },
9526 },
9527};
9528
42171c17
TI
9529/* bind hp and internal speaker mute (with plug check) as master switch */
9530static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 9531{
42171c17
TI
9532 struct alc_spec *spec = codec->spec;
9533 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9534 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9535 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9536 unsigned int mute;
0724ea2a 9537
42171c17
TI
9538 /* HP */
9539 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9540 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9541 HDA_AMP_MUTE, mute);
9542 /* mute internal speaker per jack sense */
9543 if (spec->jack_present)
9544 mute = HDA_AMP_MUTE;
9545 if (line_nid)
9546 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9547 HDA_AMP_MUTE, mute);
9548 if (speaker_nid && speaker_nid != line_nid)
9549 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 9550 HDA_AMP_MUTE, mute);
42171c17
TI
9551}
9552
9553#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9554
9555static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9556 struct snd_ctl_elem_value *ucontrol)
9557{
9558 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9559 struct alc_spec *spec = codec->spec;
9560 int val = !!*ucontrol->value.integer.value;
9561
9562 if (val == spec->master_sw)
9563 return 0;
9564 spec->master_sw = val;
9565 alc262_hippo_master_update(codec);
9566 return 1;
9567}
9568
9569#define ALC262_HIPPO_MASTER_SWITCH \
9570 { \
9571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9572 .name = "Master Playback Switch", \
9573 .info = snd_ctl_boolean_mono_info, \
9574 .get = alc262_hippo_master_sw_get, \
9575 .put = alc262_hippo_master_sw_put, \
0724ea2a 9576 }
42171c17
TI
9577
9578static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9579 ALC262_HIPPO_MASTER_SWITCH,
9580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9587 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9590 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9591 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9592 { } /* end */
9593};
9594
9595static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9596 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9597 ALC262_HIPPO_MASTER_SWITCH,
9598 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9599 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9607 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9608 { } /* end */
9609};
9610
9611/* mute/unmute internal speaker according to the hp jack and mute state */
9612static void alc262_hippo_automute(struct hda_codec *codec)
9613{
9614 struct alc_spec *spec = codec->spec;
9615 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9616 unsigned int present;
9617
9618 /* need to execute and sync at first */
9619 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9620 present = snd_hda_codec_read(codec, hp_nid, 0,
9621 AC_VERB_GET_PIN_SENSE, 0);
9622 spec->jack_present = (present & 0x80000000) != 0;
9623 alc262_hippo_master_update(codec);
0724ea2a 9624}
5b31954e 9625
42171c17
TI
9626static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9627{
9628 if ((res >> 26) != ALC880_HP_EVENT)
9629 return;
9630 alc262_hippo_automute(codec);
9631}
9632
9633static void alc262_hippo_init_hook(struct hda_codec *codec)
9634{
9635 struct alc_spec *spec = codec->spec;
9636
9637 spec->autocfg.hp_pins[0] = 0x15;
9638 spec->autocfg.speaker_pins[0] = 0x14;
9639 alc262_hippo_automute(codec);
9640}
9641
9642static void alc262_hippo1_init_hook(struct hda_codec *codec)
9643{
9644 struct alc_spec *spec = codec->spec;
9645
9646 spec->autocfg.hp_pins[0] = 0x1b;
9647 spec->autocfg.speaker_pins[0] = 0x14;
9648 alc262_hippo_automute(codec);
9649}
9650
9651
272a527c 9652static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 9653 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 9654 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
9655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9657 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9658 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9659 { } /* end */
9660};
9661
83c34218 9662static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
9663 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9664 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
9665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9668 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9669 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9670 { } /* end */
9671};
272a527c 9672
ba340e82
TV
9673static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9674 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9675 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9676 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9677 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9682 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9685 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9686 { } /* end */
9687};
9688
9689static struct hda_verb alc262_tyan_verbs[] = {
9690 /* Headphone automute */
9691 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9693 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9694
9695 /* P11 AUX_IN, white 4-pin connector */
9696 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9697 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9698 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9699 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9700
9701 {}
9702};
9703
9704/* unsolicited event for HP jack sensing */
a9fd4f3f 9705static void alc262_tyan_init_hook(struct hda_codec *codec)
ba340e82 9706{
a9fd4f3f 9707 struct alc_spec *spec = codec->spec;
ba340e82 9708
a9fd4f3f
TI
9709 spec->autocfg.hp_pins[0] = 0x1b;
9710 spec->autocfg.speaker_pins[0] = 0x15;
9711 alc_automute_amp(codec);
ba340e82
TV
9712}
9713
ba340e82 9714
9c7f852e
TI
9715#define alc262_capture_mixer alc882_capture_mixer
9716#define alc262_capture_alt_mixer alc882_capture_alt_mixer
9717
9718/*
9719 * generic initialization of ADC, input mixers and output mixers
9720 */
9721static struct hda_verb alc262_init_verbs[] = {
9722 /*
9723 * Unmute ADC0-2 and set the default input to mic-in
9724 */
9725 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9726 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9727 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9728 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9729 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9730 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9731
cb53c626 9732 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9733 * mixer widget
f12ab1e0
TI
9734 * Note: PASD motherboards uses the Line In 2 as the input for
9735 * front panel mic (mic 2)
9c7f852e
TI
9736 */
9737 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9739 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
9743
9744 /*
df694daa
KY
9745 * Set up output mixers (0x0c - 0x0e)
9746 */
9747 /* set vol=0 to output mixers */
9748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9751 /* set up input amps for analog loopback */
9752 /* Amp Indices: DAC = 0, mixer = 1 */
9753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9759
9760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9764 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9766
9767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9769 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9771 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 9772
df694daa
KY
9773 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9774 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 9775
df694daa
KY
9776 /* FIXME: use matrix-type input source selection */
9777 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9778 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9781 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9782 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9783 /* Input mixer2 */
9784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9786 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9787 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9788 /* Input mixer3 */
9789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 9792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
9793
9794 { }
9795};
1da177e4 9796
4e555fe5
KY
9797static struct hda_verb alc262_eapd_verbs[] = {
9798 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9799 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9800 { }
9801};
9802
ccc656ce
KY
9803static struct hda_verb alc262_hippo_unsol_verbs[] = {
9804 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9805 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9806 {}
9807};
9808
9809static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9811 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9812 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9813
9814 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9815 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9816 {}
9817};
9818
272a527c
KY
9819static struct hda_verb alc262_sony_unsol_verbs[] = {
9820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9822 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9823
9824 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 9826 {}
272a527c
KY
9827};
9828
4e555fe5
KY
9829static struct hda_input_mux alc262_dmic_capture_source = {
9830 .num_items = 2,
9831 .items = {
9832 { "Int DMic", 0x9 },
9833 { "Mic", 0x0 },
9834 },
9835};
9836
9837static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9838 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9839 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
9843 { } /* end */
9844};
9845
9846static struct hda_verb alc262_toshiba_s06_verbs[] = {
9847 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9850 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9851 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9852 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9853 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9854 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9855 {}
9856};
9857
9858static void alc262_dmic_automute(struct hda_codec *codec)
9859{
9860 unsigned int present;
9861
9862 present = snd_hda_codec_read(codec, 0x18, 0,
9863 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9864 snd_hda_codec_write(codec, 0x22, 0,
9865 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9866}
9867
4e555fe5
KY
9868
9869/* unsolicited event for HP jack sensing */
9870static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9871 unsigned int res)
9872{
4e555fe5
KY
9873 if ((res >> 26) == ALC880_MIC_EVENT)
9874 alc262_dmic_automute(codec);
a9fd4f3f
TI
9875 else
9876 alc_sku_unsol_event(codec, res);
4e555fe5
KY
9877}
9878
9879static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9880{
a9fd4f3f
TI
9881 struct alc_spec *spec = codec->spec;
9882
9883 spec->autocfg.hp_pins[0] = 0x15;
9884 spec->autocfg.speaker_pins[0] = 0x14;
9885 alc_automute_pin(codec);
4e555fe5
KY
9886 alc262_dmic_automute(codec);
9887}
9888
e8f9ae2a
PT
9889/*
9890 * nec model
9891 * 0x15 = headphone
9892 * 0x16 = internal speaker
9893 * 0x18 = external mic
9894 */
9895
9896static struct snd_kcontrol_new alc262_nec_mixer[] = {
9897 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9898 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9899
9900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9902 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9903
9904 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9906 { } /* end */
9907};
9908
9909static struct hda_verb alc262_nec_verbs[] = {
9910 /* Unmute Speaker */
9911 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9912
9913 /* Headphone */
9914 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9916
9917 /* External mic to headphone */
9918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9919 /* External mic to speaker */
9920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9921 {}
9922};
9923
834be88d
TI
9924/*
9925 * fujitsu model
5d9fab2d
TV
9926 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9927 * 0x1b = port replicator headphone out
834be88d
TI
9928 */
9929
9930#define ALC_HP_EVENT 0x37
9931
9932static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9933 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
9935 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
9937 {}
9938};
9939
0e31daf7
J
9940static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9943 {}
9944};
9945
834be88d 9946static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 9947 .num_items = 3,
834be88d
TI
9948 .items = {
9949 { "Mic", 0x0 },
39d3ed38 9950 { "Int Mic", 0x1 },
834be88d
TI
9951 { "CD", 0x4 },
9952 },
9953};
9954
9c7f852e
TI
9955static struct hda_input_mux alc262_HP_capture_source = {
9956 .num_items = 5,
9957 .items = {
9958 { "Mic", 0x0 },
accbe498 9959 { "Front Mic", 0x1 },
9c7f852e
TI
9960 { "Line", 0x2 },
9961 { "CD", 0x4 },
9962 { "AUX IN", 0x6 },
9963 },
9964};
9965
accbe498 9966static struct hda_input_mux alc262_HP_D7000_capture_source = {
9967 .num_items = 4,
9968 .items = {
9969 { "Mic", 0x0 },
9970 { "Front Mic", 0x2 },
9971 { "Line", 0x1 },
9972 { "CD", 0x4 },
9973 },
9974};
9975
ebc7a406 9976/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
9977static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9978{
9979 struct alc_spec *spec = codec->spec;
9980 unsigned int mute;
9981
f12ab1e0 9982 if (force || !spec->sense_updated) {
ebc7a406 9983 unsigned int present;
834be88d
TI
9984 /* need to execute and sync at first */
9985 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
9986 /* check laptop HP jack */
9987 present = snd_hda_codec_read(codec, 0x14, 0,
9988 AC_VERB_GET_PIN_SENSE, 0);
9989 /* need to execute and sync at first */
9990 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9991 /* check docking HP jack */
9992 present |= snd_hda_codec_read(codec, 0x1b, 0,
9993 AC_VERB_GET_PIN_SENSE, 0);
9994 if (present & AC_PINSENSE_PRESENCE)
9995 spec->jack_present = 1;
9996 else
9997 spec->jack_present = 0;
834be88d
TI
9998 spec->sense_updated = 1;
9999 }
ebc7a406
TI
10000 /* unmute internal speaker only if both HPs are unplugged and
10001 * master switch is on
10002 */
10003 if (spec->jack_present)
10004 mute = HDA_AMP_MUTE;
10005 else
834be88d 10006 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
10007 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10008 HDA_AMP_MUTE, mute);
834be88d
TI
10009}
10010
10011/* unsolicited event for HP jack sensing */
10012static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10013 unsigned int res)
10014{
10015 if ((res >> 26) != ALC_HP_EVENT)
10016 return;
10017 alc262_fujitsu_automute(codec, 1);
10018}
10019
ebc7a406
TI
10020static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10021{
10022 alc262_fujitsu_automute(codec, 1);
10023}
10024
834be88d 10025/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
10026static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10027 .ops = &snd_hda_bind_vol,
10028 .values = {
10029 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10030 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10031 0
10032 },
10033};
834be88d 10034
0e31daf7
J
10035/* mute/unmute internal speaker according to the hp jack and mute state */
10036static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10037{
10038 struct alc_spec *spec = codec->spec;
10039 unsigned int mute;
10040
10041 if (force || !spec->sense_updated) {
10042 unsigned int present_int_hp;
10043 /* need to execute and sync at first */
10044 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10045 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10046 AC_VERB_GET_PIN_SENSE, 0);
10047 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10048 spec->sense_updated = 1;
10049 }
10050 if (spec->jack_present) {
10051 /* mute internal speaker */
10052 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10053 HDA_AMP_MUTE, HDA_AMP_MUTE);
10054 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10055 HDA_AMP_MUTE, HDA_AMP_MUTE);
10056 } else {
10057 /* unmute internal speaker if necessary */
10058 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10059 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10060 HDA_AMP_MUTE, mute);
10061 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10062 HDA_AMP_MUTE, mute);
10063 }
10064}
10065
10066/* unsolicited event for HP jack sensing */
10067static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10068 unsigned int res)
10069{
10070 if ((res >> 26) != ALC_HP_EVENT)
10071 return;
10072 alc262_lenovo_3000_automute(codec, 1);
10073}
10074
834be88d
TI
10075/* bind hp and internal speaker mute (with plug check) */
10076static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10077 struct snd_ctl_elem_value *ucontrol)
10078{
10079 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10080 long *valp = ucontrol->value.integer.value;
10081 int change;
10082
5d9fab2d
TV
10083 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10084 HDA_AMP_MUTE,
10085 valp ? 0 : HDA_AMP_MUTE);
10086 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10087 HDA_AMP_MUTE,
10088 valp ? 0 : HDA_AMP_MUTE);
10089
82beb8fd
TI
10090 if (change)
10091 alc262_fujitsu_automute(codec, 0);
834be88d
TI
10092 return change;
10093}
10094
10095static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 10096 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
10097 {
10098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10099 .name = "Master Playback Switch",
10100 .info = snd_hda_mixer_amp_switch_info,
10101 .get = snd_hda_mixer_amp_switch_get,
10102 .put = alc262_fujitsu_master_sw_put,
10103 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10104 },
10105 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10106 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10107 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
10110 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10111 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10112 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
10113 { } /* end */
10114};
10115
0e31daf7
J
10116/* bind hp and internal speaker mute (with plug check) */
10117static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10118 struct snd_ctl_elem_value *ucontrol)
10119{
10120 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10121 long *valp = ucontrol->value.integer.value;
10122 int change;
10123
10124 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10125 HDA_AMP_MUTE,
10126 valp ? 0 : HDA_AMP_MUTE);
10127
10128 if (change)
10129 alc262_lenovo_3000_automute(codec, 0);
10130 return change;
10131}
10132
10133static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10134 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10135 {
10136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10137 .name = "Master Playback Switch",
10138 .info = snd_hda_mixer_amp_switch_info,
10139 .get = snd_hda_mixer_amp_switch_get,
10140 .put = alc262_lenovo_3000_master_sw_put,
10141 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10142 },
10143 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10144 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10145 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10148 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10149 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10150 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10151 { } /* end */
10152};
10153
9f99a638
HM
10154static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10155 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 10156 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
10157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10159 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10160 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10161 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10162 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10163 { } /* end */
10164};
10165
304dcaac
TI
10166/* additional init verbs for Benq laptops */
10167static struct hda_verb alc262_EAPD_verbs[] = {
10168 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10169 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10170 {}
10171};
10172
83c34218
KY
10173static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10174 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10175 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10176
10177 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10178 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10179 {}
10180};
10181
f651b50b
TD
10182/* Samsung Q1 Ultra Vista model setup */
10183static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
10184 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10185 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
10186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10187 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10188 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 10189 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
10190 { } /* end */
10191};
10192
10193static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
10194 /* output mixer */
10195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10197 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10198 /* speaker */
10199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10200 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10201 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10202 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10203 /* HP */
f651b50b 10204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
10205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10207 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10208 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10209 /* internal mic */
10210 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10212 /* ADC, choose mic */
10213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10214 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10215 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10216 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
10223 {}
10224};
10225
f651b50b
TD
10226/* mute/unmute internal speaker according to the hp jack and mute state */
10227static void alc262_ultra_automute(struct hda_codec *codec)
10228{
10229 struct alc_spec *spec = codec->spec;
10230 unsigned int mute;
f651b50b 10231
bb9f76cd
TI
10232 mute = 0;
10233 /* auto-mute only when HP is used as HP */
10234 if (!spec->cur_mux[0]) {
10235 unsigned int present;
10236 /* need to execute and sync at first */
10237 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10238 present = snd_hda_codec_read(codec, 0x15, 0,
10239 AC_VERB_GET_PIN_SENSE, 0);
10240 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10241 if (spec->jack_present)
10242 mute = HDA_AMP_MUTE;
f651b50b 10243 }
bb9f76cd
TI
10244 /* mute/unmute internal speaker */
10245 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10246 HDA_AMP_MUTE, mute);
10247 /* mute/unmute HP */
10248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10249 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
10250}
10251
10252/* unsolicited event for HP jack sensing */
10253static void alc262_ultra_unsol_event(struct hda_codec *codec,
10254 unsigned int res)
10255{
10256 if ((res >> 26) != ALC880_HP_EVENT)
10257 return;
10258 alc262_ultra_automute(codec);
10259}
10260
bb9f76cd
TI
10261static struct hda_input_mux alc262_ultra_capture_source = {
10262 .num_items = 2,
10263 .items = {
10264 { "Mic", 0x1 },
10265 { "Headphone", 0x7 },
10266 },
10267};
10268
10269static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10270 struct snd_ctl_elem_value *ucontrol)
10271{
10272 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10273 struct alc_spec *spec = codec->spec;
10274 int ret;
10275
54cbc9ab 10276 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
10277 if (!ret)
10278 return 0;
10279 /* reprogram the HP pin as mic or HP according to the input source */
10280 snd_hda_codec_write_cache(codec, 0x15, 0,
10281 AC_VERB_SET_PIN_WIDGET_CONTROL,
10282 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10283 alc262_ultra_automute(codec); /* mute/unmute HP */
10284 return ret;
10285}
10286
10287static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10288 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10289 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10290 {
10291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10292 .name = "Capture Source",
54cbc9ab
TI
10293 .info = alc_mux_enum_info,
10294 .get = alc_mux_enum_get,
bb9f76cd
TI
10295 .put = alc262_ultra_mux_enum_put,
10296 },
10297 { } /* end */
10298};
10299
df694daa 10300/* add playback controls from the parsed DAC table */
f12ab1e0
TI
10301static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10302 const struct auto_pin_cfg *cfg)
df694daa
KY
10303{
10304 hda_nid_t nid;
10305 int err;
10306
10307 spec->multiout.num_dacs = 1; /* only use one dac */
10308 spec->multiout.dac_nids = spec->private_dac_nids;
10309 spec->multiout.dac_nids[0] = 2;
10310
10311 nid = cfg->line_out_pins[0];
10312 if (nid) {
f12ab1e0
TI
10313 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10314 "Front Playback Volume",
10315 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10316 if (err < 0)
df694daa 10317 return err;
f12ab1e0
TI
10318 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10319 "Front Playback Switch",
10320 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10321 if (err < 0)
df694daa
KY
10322 return err;
10323 }
10324
82bc955f 10325 nid = cfg->speaker_pins[0];
df694daa
KY
10326 if (nid) {
10327 if (nid == 0x16) {
f12ab1e0
TI
10328 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10329 "Speaker Playback Volume",
10330 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10331 HDA_OUTPUT));
10332 if (err < 0)
df694daa 10333 return err;
f12ab1e0
TI
10334 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10335 "Speaker Playback Switch",
10336 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10337 HDA_OUTPUT));
10338 if (err < 0)
df694daa
KY
10339 return err;
10340 } else {
f12ab1e0
TI
10341 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10342 "Speaker Playback Switch",
10343 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10344 HDA_OUTPUT));
10345 if (err < 0)
df694daa
KY
10346 return err;
10347 }
10348 }
eb06ed8f 10349 nid = cfg->hp_pins[0];
df694daa
KY
10350 if (nid) {
10351 /* spec->multiout.hp_nid = 2; */
10352 if (nid == 0x16) {
f12ab1e0
TI
10353 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10354 "Headphone Playback Volume",
10355 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10356 HDA_OUTPUT));
10357 if (err < 0)
df694daa 10358 return err;
f12ab1e0
TI
10359 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10360 "Headphone Playback Switch",
10361 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10362 HDA_OUTPUT));
10363 if (err < 0)
df694daa
KY
10364 return err;
10365 } else {
f12ab1e0
TI
10366 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10367 "Headphone Playback Switch",
10368 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10369 HDA_OUTPUT));
10370 if (err < 0)
df694daa
KY
10371 return err;
10372 }
10373 }
f12ab1e0 10374 return 0;
df694daa
KY
10375}
10376
10377/* identical with ALC880 */
f12ab1e0
TI
10378#define alc262_auto_create_analog_input_ctls \
10379 alc880_auto_create_analog_input_ctls
df694daa
KY
10380
10381/*
10382 * generic initialization of ADC, input mixers and output mixers
10383 */
10384static struct hda_verb alc262_volume_init_verbs[] = {
10385 /*
10386 * Unmute ADC0-2 and set the default input to mic-in
10387 */
10388 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10390 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10392 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10394
cb53c626 10395 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10396 * mixer widget
f12ab1e0
TI
10397 * Note: PASD motherboards uses the Line In 2 as the input for
10398 * front panel mic (mic 2)
df694daa
KY
10399 */
10400 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10406
10407 /*
10408 * Set up output mixers (0x0c - 0x0f)
10409 */
10410 /* set vol=0 to output mixers */
10411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10414
df694daa
KY
10415 /* set up input amps for analog loopback */
10416 /* Amp Indices: DAC = 0, mixer = 1 */
10417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10421 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10422 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10423
10424 /* FIXME: use matrix-type input source selection */
10425 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10426 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10429 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10430 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10431 /* Input mixer2 */
10432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10433 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10434 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10436 /* Input mixer3 */
10437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10440 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10441
10442 { }
10443};
10444
9c7f852e
TI
10445static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10446 /*
10447 * Unmute ADC0-2 and set the default input to mic-in
10448 */
10449 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10451 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10452 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10453 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10454 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10455
cb53c626 10456 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10457 * mixer widget
f12ab1e0
TI
10458 * Note: PASD motherboards uses the Line In 2 as the input for
10459 * front panel mic (mic 2)
9c7f852e
TI
10460 */
10461 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10463 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10464 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10466 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10467 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10468 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10469
9c7f852e
TI
10470 /*
10471 * Set up output mixers (0x0c - 0x0e)
10472 */
10473 /* set vol=0 to output mixers */
10474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10477
10478 /* set up input amps for analog loopback */
10479 /* Amp Indices: DAC = 0, mixer = 1 */
10480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10486
ce875f07 10487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10490
10491 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10493
10494 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10495 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10496
10497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10499 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10500 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10502
10503 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10504 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10507 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10508 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10509
10510
10511 /* FIXME: use matrix-type input source selection */
10512 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10513 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10514 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10518 /* Input mixer2 */
10519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10523 /* Input mixer3 */
10524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10528
ce875f07
TI
10529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10530
9c7f852e
TI
10531 { }
10532};
10533
cd7509a4
KY
10534static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10535 /*
10536 * Unmute ADC0-2 and set the default input to mic-in
10537 */
10538 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10540 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10541 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10542 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10543 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10544
cb53c626 10545 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10546 * mixer widget
10547 * Note: PASD motherboards uses the Line In 2 as the input for front
10548 * panel mic (mic 2)
10549 */
10550 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10559 /*
10560 * Set up output mixers (0x0c - 0x0e)
10561 */
10562 /* set vol=0 to output mixers */
10563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10566
10567 /* set up input amps for analog loopback */
10568 /* Amp Indices: DAC = 0, mixer = 1 */
10569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10570 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10571 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10573 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10575
10576
10577 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10578 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10583 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10584
10585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10587
10588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10589 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10590
10591 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10593 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10594 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10595 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10596 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10597
10598 /* FIXME: use matrix-type input source selection */
10599 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10600 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10604 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10605 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10606 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10608 /* Input mixer2 */
10609 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10610 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10614 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10616 /* Input mixer3 */
10617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10622 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10624
ce875f07
TI
10625 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10626
cd7509a4
KY
10627 { }
10628};
10629
9f99a638
HM
10630static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10631
10632 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10633 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10634 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10635
10636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10638 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10639 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10640
10641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10643 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10644 {}
10645};
10646
10647
cb53c626
TI
10648#ifdef CONFIG_SND_HDA_POWER_SAVE
10649#define alc262_loopbacks alc880_loopbacks
10650#endif
10651
df694daa
KY
10652/* pcm configuration: identiacal with ALC880 */
10653#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10654#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10655#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10656#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10657
10658/*
10659 * BIOS auto configuration
10660 */
10661static int alc262_parse_auto_config(struct hda_codec *codec)
10662{
10663 struct alc_spec *spec = codec->spec;
10664 int err;
10665 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10666
f12ab1e0
TI
10667 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10668 alc262_ignore);
10669 if (err < 0)
df694daa 10670 return err;
e64f14f4 10671 if (!spec->autocfg.line_outs) {
0852d7a6 10672 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
10673 spec->multiout.max_channels = 2;
10674 spec->no_analog = 1;
10675 goto dig_only;
10676 }
df694daa 10677 return 0; /* can't find valid BIOS pin config */
e64f14f4 10678 }
f12ab1e0
TI
10679 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10680 if (err < 0)
10681 return err;
10682 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10683 if (err < 0)
df694daa
KY
10684 return err;
10685
10686 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10687
e64f14f4 10688 dig_only:
0852d7a6 10689 if (spec->autocfg.dig_outs) {
df694daa 10690 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 10691 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 10692 }
df694daa
KY
10693 if (spec->autocfg.dig_in_pin)
10694 spec->dig_in_nid = ALC262_DIGIN_NID;
10695
603c4019 10696 if (spec->kctls.list)
d88897ea 10697 add_mixer(spec, spec->kctls.list);
df694daa 10698
d88897ea 10699 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 10700 spec->num_mux_defs = 1;
61b9b9b1 10701 spec->input_mux = &spec->private_imux[0];
df694daa 10702
776e184e
TI
10703 err = alc_auto_add_mic_boost(codec);
10704 if (err < 0)
10705 return err;
10706
4a79ba34
TI
10707 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10708
df694daa
KY
10709 return 1;
10710}
10711
10712#define alc262_auto_init_multi_out alc882_auto_init_multi_out
10713#define alc262_auto_init_hp_out alc882_auto_init_hp_out
10714#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 10715#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
10716
10717
10718/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 10719static void alc262_auto_init(struct hda_codec *codec)
df694daa 10720{
f6c7e546 10721 struct alc_spec *spec = codec->spec;
df694daa
KY
10722 alc262_auto_init_multi_out(codec);
10723 alc262_auto_init_hp_out(codec);
10724 alc262_auto_init_analog_input(codec);
f511b01c 10725 alc262_auto_init_input_src(codec);
f6c7e546 10726 if (spec->unsol_event)
7fb0d78f 10727 alc_inithook(codec);
df694daa
KY
10728}
10729
10730/*
10731 * configuration and preset
10732 */
f5fcc13c
TI
10733static const char *alc262_models[ALC262_MODEL_LAST] = {
10734 [ALC262_BASIC] = "basic",
10735 [ALC262_HIPPO] = "hippo",
10736 [ALC262_HIPPO_1] = "hippo_1",
10737 [ALC262_FUJITSU] = "fujitsu",
10738 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 10739 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 10740 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 10741 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 10742 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
10743 [ALC262_BENQ_T31] = "benq-t31",
10744 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 10745 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 10746 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 10747 [ALC262_ULTRA] = "ultra",
0e31daf7 10748 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 10749 [ALC262_NEC] = "nec",
ba340e82 10750 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
10751 [ALC262_AUTO] = "auto",
10752};
10753
10754static struct snd_pci_quirk alc262_cfg_tbl[] = {
10755 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 10756 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
10757 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10758 ALC262_HP_BPC),
10759 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10760 ALC262_HP_BPC),
53eff7e1
TI
10761 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10762 ALC262_HP_BPC),
cd7509a4 10763 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10764 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10765 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10766 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10767 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10768 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10769 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10770 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
10771 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10772 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10773 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
10774 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10775 ALC262_HP_TC_T5735),
8c427226 10776 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 10777 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 10778 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 10779 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 10780 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
f872a919
TI
10781 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10782 ALC262_SONY_ASSAMD),
36ca6e13 10783 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 10784 ALC262_TOSHIBA_RX1),
80ffe869 10785 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 10786 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 10787 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 10788 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
10789 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10790 ALC262_ULTRA),
3e420e78 10791 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 10792 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
10793 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10794 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10795 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
10796 {}
10797};
10798
10799static struct alc_config_preset alc262_presets[] = {
10800 [ALC262_BASIC] = {
10801 .mixers = { alc262_base_mixer },
10802 .init_verbs = { alc262_init_verbs },
10803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10804 .dac_nids = alc262_dac_nids,
10805 .hp_nid = 0x03,
10806 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10807 .channel_mode = alc262_modes,
a3bcba38 10808 .input_mux = &alc262_capture_source,
df694daa 10809 },
ccc656ce 10810 [ALC262_HIPPO] = {
42171c17 10811 .mixers = { alc262_hippo_mixer },
ccc656ce
KY
10812 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10813 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10814 .dac_nids = alc262_dac_nids,
10815 .hp_nid = 0x03,
10816 .dig_out_nid = ALC262_DIGOUT_NID,
10817 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10818 .channel_mode = alc262_modes,
10819 .input_mux = &alc262_capture_source,
10820 .unsol_event = alc262_hippo_unsol_event,
42171c17 10821 .init_hook = alc262_hippo_init_hook,
ccc656ce
KY
10822 },
10823 [ALC262_HIPPO_1] = {
10824 .mixers = { alc262_hippo1_mixer },
10825 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10826 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10827 .dac_nids = alc262_dac_nids,
10828 .hp_nid = 0x02,
10829 .dig_out_nid = ALC262_DIGOUT_NID,
10830 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10831 .channel_mode = alc262_modes,
10832 .input_mux = &alc262_capture_source,
42171c17
TI
10833 .unsol_event = alc262_hippo_unsol_event,
10834 .init_hook = alc262_hippo1_init_hook,
ccc656ce 10835 },
834be88d
TI
10836 [ALC262_FUJITSU] = {
10837 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
10838 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10839 alc262_fujitsu_unsol_verbs },
834be88d
TI
10840 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10841 .dac_nids = alc262_dac_nids,
10842 .hp_nid = 0x03,
10843 .dig_out_nid = ALC262_DIGOUT_NID,
10844 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10845 .channel_mode = alc262_modes,
10846 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 10847 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 10848 .init_hook = alc262_fujitsu_init_hook,
834be88d 10849 },
9c7f852e
TI
10850 [ALC262_HP_BPC] = {
10851 .mixers = { alc262_HP_BPC_mixer },
10852 .init_verbs = { alc262_HP_BPC_init_verbs },
10853 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10854 .dac_nids = alc262_dac_nids,
10855 .hp_nid = 0x03,
10856 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10857 .channel_mode = alc262_modes,
10858 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
10859 .unsol_event = alc262_hp_bpc_unsol_event,
10860 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 10861 },
cd7509a4
KY
10862 [ALC262_HP_BPC_D7000_WF] = {
10863 .mixers = { alc262_HP_BPC_WildWest_mixer },
10864 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10865 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10866 .dac_nids = alc262_dac_nids,
10867 .hp_nid = 0x03,
10868 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10869 .channel_mode = alc262_modes,
accbe498 10870 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10871 .unsol_event = alc262_hp_wildwest_unsol_event,
10872 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10873 },
cd7509a4
KY
10874 [ALC262_HP_BPC_D7000_WL] = {
10875 .mixers = { alc262_HP_BPC_WildWest_mixer,
10876 alc262_HP_BPC_WildWest_option_mixer },
10877 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10878 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10879 .dac_nids = alc262_dac_nids,
10880 .hp_nid = 0x03,
10881 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10882 .channel_mode = alc262_modes,
accbe498 10883 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10884 .unsol_event = alc262_hp_wildwest_unsol_event,
10885 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10886 },
66d2a9d6
KY
10887 [ALC262_HP_TC_T5735] = {
10888 .mixers = { alc262_hp_t5735_mixer },
10889 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10890 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10891 .dac_nids = alc262_dac_nids,
10892 .hp_nid = 0x03,
10893 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10894 .channel_mode = alc262_modes,
10895 .input_mux = &alc262_capture_source,
a9fd4f3f 10896 .unsol_event = alc_automute_amp_unsol_event,
66d2a9d6 10897 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
10898 },
10899 [ALC262_HP_RP5700] = {
10900 .mixers = { alc262_hp_rp5700_mixer },
10901 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10902 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10903 .dac_nids = alc262_dac_nids,
10904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10905 .channel_mode = alc262_modes,
10906 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 10907 },
304dcaac
TI
10908 [ALC262_BENQ_ED8] = {
10909 .mixers = { alc262_base_mixer },
10910 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10911 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10912 .dac_nids = alc262_dac_nids,
10913 .hp_nid = 0x03,
10914 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10915 .channel_mode = alc262_modes,
10916 .input_mux = &alc262_capture_source,
f12ab1e0 10917 },
272a527c
KY
10918 [ALC262_SONY_ASSAMD] = {
10919 .mixers = { alc262_sony_mixer },
10920 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10921 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10922 .dac_nids = alc262_dac_nids,
10923 .hp_nid = 0x02,
10924 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10925 .channel_mode = alc262_modes,
10926 .input_mux = &alc262_capture_source,
10927 .unsol_event = alc262_hippo_unsol_event,
42171c17 10928 .init_hook = alc262_hippo_init_hook,
83c34218
KY
10929 },
10930 [ALC262_BENQ_T31] = {
10931 .mixers = { alc262_benq_t31_mixer },
10932 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10933 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10934 .dac_nids = alc262_dac_nids,
10935 .hp_nid = 0x03,
10936 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10937 .channel_mode = alc262_modes,
10938 .input_mux = &alc262_capture_source,
10939 .unsol_event = alc262_hippo_unsol_event,
42171c17 10940 .init_hook = alc262_hippo_init_hook,
ea1fb29a 10941 },
f651b50b 10942 [ALC262_ULTRA] = {
f9e336f6
TI
10943 .mixers = { alc262_ultra_mixer },
10944 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 10945 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
10946 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10947 .dac_nids = alc262_dac_nids,
f651b50b
TD
10948 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10949 .channel_mode = alc262_modes,
10950 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
10951 .adc_nids = alc262_adc_nids, /* ADC0 */
10952 .capsrc_nids = alc262_capsrc_nids,
10953 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
10954 .unsol_event = alc262_ultra_unsol_event,
10955 .init_hook = alc262_ultra_automute,
10956 },
0e31daf7
J
10957 [ALC262_LENOVO_3000] = {
10958 .mixers = { alc262_lenovo_3000_mixer },
10959 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10960 alc262_lenovo_3000_unsol_verbs },
10961 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10962 .dac_nids = alc262_dac_nids,
10963 .hp_nid = 0x03,
10964 .dig_out_nid = ALC262_DIGOUT_NID,
10965 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10966 .channel_mode = alc262_modes,
10967 .input_mux = &alc262_fujitsu_capture_source,
10968 .unsol_event = alc262_lenovo_3000_unsol_event,
10969 },
e8f9ae2a
PT
10970 [ALC262_NEC] = {
10971 .mixers = { alc262_nec_mixer },
10972 .init_verbs = { alc262_nec_verbs },
10973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10974 .dac_nids = alc262_dac_nids,
10975 .hp_nid = 0x03,
10976 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10977 .channel_mode = alc262_modes,
10978 .input_mux = &alc262_capture_source,
10979 },
4e555fe5
KY
10980 [ALC262_TOSHIBA_S06] = {
10981 .mixers = { alc262_toshiba_s06_mixer },
10982 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10983 alc262_eapd_verbs },
10984 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10985 .capsrc_nids = alc262_dmic_capsrc_nids,
10986 .dac_nids = alc262_dac_nids,
10987 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10988 .dig_out_nid = ALC262_DIGOUT_NID,
10989 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10990 .channel_mode = alc262_modes,
10991 .input_mux = &alc262_dmic_capture_source,
10992 .unsol_event = alc262_toshiba_s06_unsol_event,
10993 .init_hook = alc262_toshiba_s06_init_hook,
10994 },
9f99a638
HM
10995 [ALC262_TOSHIBA_RX1] = {
10996 .mixers = { alc262_toshiba_rx1_mixer },
10997 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10998 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10999 .dac_nids = alc262_dac_nids,
11000 .hp_nid = 0x03,
11001 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11002 .channel_mode = alc262_modes,
11003 .input_mux = &alc262_capture_source,
11004 .unsol_event = alc262_hippo_unsol_event,
42171c17 11005 .init_hook = alc262_hippo_init_hook,
9f99a638 11006 },
ba340e82
TV
11007 [ALC262_TYAN] = {
11008 .mixers = { alc262_tyan_mixer },
11009 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11010 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11011 .dac_nids = alc262_dac_nids,
11012 .hp_nid = 0x02,
11013 .dig_out_nid = ALC262_DIGOUT_NID,
11014 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11015 .channel_mode = alc262_modes,
11016 .input_mux = &alc262_capture_source,
a9fd4f3f
TI
11017 .unsol_event = alc_automute_amp_unsol_event,
11018 .init_hook = alc262_tyan_init_hook,
ba340e82 11019 },
df694daa
KY
11020};
11021
11022static int patch_alc262(struct hda_codec *codec)
11023{
11024 struct alc_spec *spec;
11025 int board_config;
11026 int err;
11027
dc041e0b 11028 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11029 if (spec == NULL)
11030 return -ENOMEM;
11031
11032 codec->spec = spec;
11033#if 0
f12ab1e0
TI
11034 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11035 * under-run
11036 */
df694daa
KY
11037 {
11038 int tmp;
11039 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11040 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11041 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11042 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11043 }
11044#endif
11045
2c3bf9ab
TI
11046 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11047
f5fcc13c
TI
11048 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11049 alc262_models,
11050 alc262_cfg_tbl);
cd7509a4 11051
f5fcc13c 11052 if (board_config < 0) {
9c7f852e
TI
11053 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11054 "trying auto-probe from BIOS...\n");
df694daa
KY
11055 board_config = ALC262_AUTO;
11056 }
11057
11058 if (board_config == ALC262_AUTO) {
11059 /* automatic parse from the BIOS config */
11060 err = alc262_parse_auto_config(codec);
11061 if (err < 0) {
11062 alc_free(codec);
11063 return err;
f12ab1e0 11064 } else if (!err) {
9c7f852e
TI
11065 printk(KERN_INFO
11066 "hda_codec: Cannot set up configuration "
11067 "from BIOS. Using base mode...\n");
df694daa
KY
11068 board_config = ALC262_BASIC;
11069 }
11070 }
11071
07eba61d
TI
11072 if (!spec->no_analog) {
11073 err = snd_hda_attach_beep_device(codec, 0x1);
11074 if (err < 0) {
11075 alc_free(codec);
11076 return err;
11077 }
680cd536
KK
11078 }
11079
df694daa
KY
11080 if (board_config != ALC262_AUTO)
11081 setup_preset(spec, &alc262_presets[board_config]);
11082
11083 spec->stream_name_analog = "ALC262 Analog";
11084 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11085 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 11086
df694daa
KY
11087 spec->stream_name_digital = "ALC262 Digital";
11088 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11089 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11090
61b9b9b1 11091 spec->capture_style = CAPT_MIX;
f12ab1e0 11092 if (!spec->adc_nids && spec->input_mux) {
df694daa 11093 /* check whether NID 0x07 is valid */
4a471b7d
TI
11094 unsigned int wcap = get_wcaps(codec, 0x07);
11095
f12ab1e0
TI
11096 /* get type */
11097 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
11098 if (wcap != AC_WID_AUD_IN) {
11099 spec->adc_nids = alc262_adc_nids_alt;
11100 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 11101 spec->capsrc_nids = alc262_capsrc_nids_alt;
df694daa
KY
11102 } else {
11103 spec->adc_nids = alc262_adc_nids;
11104 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 11105 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
11106 }
11107 }
e64f14f4 11108 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 11109 set_capture_mixer(spec);
07eba61d
TI
11110 if (!spec->no_analog)
11111 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 11112
2134ea4f
TI
11113 spec->vmaster_nid = 0x0c;
11114
df694daa
KY
11115 codec->patch_ops = alc_patch_ops;
11116 if (board_config == ALC262_AUTO)
ae6b813a 11117 spec->init_hook = alc262_auto_init;
cb53c626
TI
11118#ifdef CONFIG_SND_HDA_POWER_SAVE
11119 if (!spec->loopback.amplist)
11120 spec->loopback.amplist = alc262_loopbacks;
11121#endif
daead538 11122 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 11123
df694daa
KY
11124 return 0;
11125}
11126
a361d84b
KY
11127/*
11128 * ALC268 channel source setting (2 channel)
11129 */
11130#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11131#define alc268_modes alc260_modes
ea1fb29a 11132
a361d84b
KY
11133static hda_nid_t alc268_dac_nids[2] = {
11134 /* front, hp */
11135 0x02, 0x03
11136};
11137
11138static hda_nid_t alc268_adc_nids[2] = {
11139 /* ADC0-1 */
11140 0x08, 0x07
11141};
11142
11143static hda_nid_t alc268_adc_nids_alt[1] = {
11144 /* ADC0 */
11145 0x08
11146};
11147
e1406348
TI
11148static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11149
a361d84b
KY
11150static struct snd_kcontrol_new alc268_base_mixer[] = {
11151 /* output mixer control */
11152 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11153 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
11156 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11157 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11158 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
11159 { }
11160};
11161
42171c17
TI
11162static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11163 /* output mixer control */
11164 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11166 ALC262_HIPPO_MASTER_SWITCH,
11167 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11168 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11169 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11170 { }
11171};
11172
aef9d318
TI
11173/* bind Beep switches of both NID 0x0f and 0x10 */
11174static struct hda_bind_ctls alc268_bind_beep_sw = {
11175 .ops = &snd_hda_bind_sw,
11176 .values = {
11177 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11178 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11179 0
11180 },
11181};
11182
11183static struct snd_kcontrol_new alc268_beep_mixer[] = {
11184 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11185 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11186 { }
11187};
11188
d1a991a6
KY
11189static struct hda_verb alc268_eapd_verbs[] = {
11190 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11191 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11192 { }
11193};
11194
d273809e 11195/* Toshiba specific */
d273809e
TI
11196static struct hda_verb alc268_toshiba_verbs[] = {
11197 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11198 { } /* end */
11199};
11200
8ef355da
KY
11201static struct hda_input_mux alc268_acer_lc_capture_source = {
11202 .num_items = 2,
11203 .items = {
11204 { "i-Mic", 0x6 },
11205 { "E-Mic", 0x0 },
11206 },
11207};
11208
d273809e 11209/* Acer specific */
889c4395 11210/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
11211static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11212 .ops = &snd_hda_bind_vol,
11213 .values = {
11214 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11215 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11216 0
11217 },
11218};
11219
889c4395
TI
11220/* mute/unmute internal speaker according to the hp jack and mute state */
11221static void alc268_acer_automute(struct hda_codec *codec, int force)
11222{
11223 struct alc_spec *spec = codec->spec;
11224 unsigned int mute;
11225
11226 if (force || !spec->sense_updated) {
11227 unsigned int present;
11228 present = snd_hda_codec_read(codec, 0x14, 0,
11229 AC_VERB_GET_PIN_SENSE, 0);
11230 spec->jack_present = (present & 0x80000000) != 0;
11231 spec->sense_updated = 1;
11232 }
11233 if (spec->jack_present)
11234 mute = HDA_AMP_MUTE; /* mute internal speaker */
11235 else /* unmute internal speaker if necessary */
11236 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11237 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11238 HDA_AMP_MUTE, mute);
11239}
11240
11241
11242/* bind hp and internal speaker mute (with plug check) */
11243static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11244 struct snd_ctl_elem_value *ucontrol)
11245{
11246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11247 long *valp = ucontrol->value.integer.value;
11248 int change;
11249
11250 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11251 HDA_AMP_MUTE,
11252 valp[0] ? 0 : HDA_AMP_MUTE);
11253 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11254 HDA_AMP_MUTE,
11255 valp[1] ? 0 : HDA_AMP_MUTE);
11256 if (change)
11257 alc268_acer_automute(codec, 0);
11258 return change;
11259}
d273809e 11260
8ef355da
KY
11261static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11262 /* output mixer control */
11263 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11264 {
11265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11266 .name = "Master Playback Switch",
11267 .info = snd_hda_mixer_amp_switch_info,
11268 .get = snd_hda_mixer_amp_switch_get,
11269 .put = alc268_acer_master_sw_put,
11270 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11271 },
11272 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11273 { }
11274};
11275
d273809e
TI
11276static struct snd_kcontrol_new alc268_acer_mixer[] = {
11277 /* output mixer control */
11278 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11279 {
11280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11281 .name = "Master Playback Switch",
11282 .info = snd_hda_mixer_amp_switch_info,
11283 .get = snd_hda_mixer_amp_switch_get,
11284 .put = alc268_acer_master_sw_put,
11285 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11286 },
33bf17ab
TI
11287 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11289 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
11290 { }
11291};
11292
c238b4f4
TI
11293static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11294 /* output mixer control */
11295 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11296 {
11297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11298 .name = "Master Playback Switch",
11299 .info = snd_hda_mixer_amp_switch_info,
11300 .get = snd_hda_mixer_amp_switch_get,
11301 .put = alc268_acer_master_sw_put,
11302 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11303 },
11304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11305 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11306 { }
11307};
11308
8ef355da
KY
11309static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11310 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11312 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11313 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11314 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11316 { }
11317};
11318
d273809e 11319static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
11320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11321 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
11322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
11324 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
11326 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11327 { }
11328};
11329
11330/* unsolicited event for HP jack sensing */
42171c17
TI
11331#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11332#define alc268_toshiba_init_hook alc262_hippo_init_hook
d273809e
TI
11333
11334static void alc268_acer_unsol_event(struct hda_codec *codec,
11335 unsigned int res)
11336{
889c4395 11337 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11338 return;
11339 alc268_acer_automute(codec, 1);
11340}
11341
889c4395
TI
11342static void alc268_acer_init_hook(struct hda_codec *codec)
11343{
11344 alc268_acer_automute(codec, 1);
11345}
11346
8ef355da
KY
11347/* toggle speaker-output according to the hp-jack state */
11348static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11349{
11350 unsigned int present;
11351 unsigned char bits;
11352
11353 present = snd_hda_codec_read(codec, 0x15, 0,
11354 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11355 bits = present ? AMP_IN_MUTE(0) : 0;
11356 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11357 AMP_IN_MUTE(0), bits);
11358 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11359 AMP_IN_MUTE(0), bits);
11360}
11361
11362
11363static void alc268_acer_mic_automute(struct hda_codec *codec)
11364{
11365 unsigned int present;
11366
11367 present = snd_hda_codec_read(codec, 0x18, 0,
11368 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11369 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11370 present ? 0x0 : 0x6);
11371}
11372
11373static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11374 unsigned int res)
11375{
11376 if ((res >> 26) == ALC880_HP_EVENT)
11377 alc268_aspire_one_speaker_automute(codec);
11378 if ((res >> 26) == ALC880_MIC_EVENT)
11379 alc268_acer_mic_automute(codec);
11380}
11381
11382static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11383{
11384 alc268_aspire_one_speaker_automute(codec);
11385 alc268_acer_mic_automute(codec);
11386}
11387
3866f0b0
TI
11388static struct snd_kcontrol_new alc268_dell_mixer[] = {
11389 /* output mixer control */
11390 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11391 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11392 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11393 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11394 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11395 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11396 { }
11397};
11398
11399static struct hda_verb alc268_dell_verbs[] = {
11400 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11403 { }
11404};
11405
11406/* mute/unmute internal speaker according to the hp jack and mute state */
a9fd4f3f 11407static void alc268_dell_init_hook(struct hda_codec *codec)
3866f0b0 11408{
a9fd4f3f 11409 struct alc_spec *spec = codec->spec;
3866f0b0 11410
a9fd4f3f
TI
11411 spec->autocfg.hp_pins[0] = 0x15;
11412 spec->autocfg.speaker_pins[0] = 0x14;
11413 alc_automute_pin(codec);
3866f0b0
TI
11414}
11415
eb5a6621
HRK
11416static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11417 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11418 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11419 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11421 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11422 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11423 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11424 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11425 { }
11426};
11427
11428static struct hda_verb alc267_quanta_il1_verbs[] = {
11429 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11430 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11431 { }
11432};
11433
eb5a6621
HRK
11434static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11435{
11436 unsigned int present;
11437
11438 present = snd_hda_codec_read(codec, 0x18, 0,
11439 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11440 snd_hda_codec_write(codec, 0x23, 0,
11441 AC_VERB_SET_CONNECT_SEL,
11442 present ? 0x00 : 0x01);
11443}
11444
a9fd4f3f 11445static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
eb5a6621 11446{
a9fd4f3f
TI
11447 struct alc_spec *spec = codec->spec;
11448
11449 spec->autocfg.hp_pins[0] = 0x15;
11450 spec->autocfg.speaker_pins[0] = 0x14;
11451 alc_automute_pin(codec);
eb5a6621
HRK
11452 alc267_quanta_il1_mic_automute(codec);
11453}
11454
11455static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11456 unsigned int res)
11457{
11458 switch (res >> 26) {
eb5a6621
HRK
11459 case ALC880_MIC_EVENT:
11460 alc267_quanta_il1_mic_automute(codec);
11461 break;
a9fd4f3f
TI
11462 default:
11463 alc_sku_unsol_event(codec, res);
11464 break;
eb5a6621
HRK
11465 }
11466}
11467
a361d84b
KY
11468/*
11469 * generic initialization of ADC, input mixers and output mixers
11470 */
11471static struct hda_verb alc268_base_init_verbs[] = {
11472 /* Unmute DAC0-1 and set vol = 0 */
11473 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 11474 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11475
11476 /*
11477 * Set up output mixers (0x0c - 0x0e)
11478 */
11479 /* set vol=0 to output mixers */
11480 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11481 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11482
11483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11484 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11485
11486 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11490 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11492 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11493 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11494
11495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11497 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11498 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11499 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
11500
11501 /* set PCBEEP vol = 0, mute connections */
11502 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11503 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11504 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 11505
a9b3aa8a 11506 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 11507
a9b3aa8a
JZ
11508 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11510 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11511 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11512
a361d84b
KY
11513 { }
11514};
11515
11516/*
11517 * generic initialization of ADC, input mixers and output mixers
11518 */
11519static struct hda_verb alc268_volume_init_verbs[] = {
11520 /* set output DAC */
4cfb91c6
TI
11521 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11522 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11523
11524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11527 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11528 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11529
a361d84b 11530 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11531 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11532 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11533
11534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11535 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11536
aef9d318
TI
11537 /* set PCBEEP vol = 0, mute connections */
11538 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11540 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11541
11542 { }
11543};
11544
a361d84b
KY
11545static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11546 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11547 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11548 {
11549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11550 /* The multiple "Capture Source" controls confuse alsamixer
11551 * So call somewhat different..
a361d84b
KY
11552 */
11553 /* .name = "Capture Source", */
11554 .name = "Input Source",
11555 .count = 1,
54cbc9ab
TI
11556 .info = alc_mux_enum_info,
11557 .get = alc_mux_enum_get,
11558 .put = alc_mux_enum_put,
a361d84b
KY
11559 },
11560 { } /* end */
11561};
11562
11563static struct snd_kcontrol_new alc268_capture_mixer[] = {
11564 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11565 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11567 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11568 {
11569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11570 /* The multiple "Capture Source" controls confuse alsamixer
11571 * So call somewhat different..
a361d84b
KY
11572 */
11573 /* .name = "Capture Source", */
11574 .name = "Input Source",
11575 .count = 2,
54cbc9ab
TI
11576 .info = alc_mux_enum_info,
11577 .get = alc_mux_enum_get,
11578 .put = alc_mux_enum_put,
a361d84b
KY
11579 },
11580 { } /* end */
11581};
11582
11583static struct hda_input_mux alc268_capture_source = {
11584 .num_items = 4,
11585 .items = {
11586 { "Mic", 0x0 },
11587 { "Front Mic", 0x1 },
11588 { "Line", 0x2 },
11589 { "CD", 0x3 },
11590 },
11591};
11592
0ccb541c 11593static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
11594 .num_items = 3,
11595 .items = {
11596 { "Mic", 0x0 },
11597 { "Internal Mic", 0x1 },
11598 { "Line", 0x2 },
11599 },
11600};
11601
11602static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
11603 .num_items = 3,
11604 .items = {
11605 { "Mic", 0x0 },
11606 { "Internal Mic", 0x6 },
11607 { "Line", 0x2 },
11608 },
11609};
11610
86c53bd2
JW
11611#ifdef CONFIG_SND_DEBUG
11612static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11613 /* Volume widgets */
11614 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11615 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11616 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11617 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11618 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11619 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11620 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11621 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11622 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11623 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11624 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11625 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11626 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11627 /* The below appears problematic on some hardwares */
11628 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11629 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11630 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11631 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11632 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11633
11634 /* Modes for retasking pin widgets */
11635 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11636 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11637 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11638 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11639
11640 /* Controls for GPIO pins, assuming they are configured as outputs */
11641 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11642 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11643 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11644 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11645
11646 /* Switches to allow the digital SPDIF output pin to be enabled.
11647 * The ALC268 does not have an SPDIF input.
11648 */
11649 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11650
11651 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11652 * this output to turn on an external amplifier.
11653 */
11654 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11655 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11656
11657 { } /* end */
11658};
11659#endif
11660
a361d84b
KY
11661/* create input playback/capture controls for the given pin */
11662static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11663 const char *ctlname, int idx)
11664{
11665 char name[32];
11666 int err;
11667
11668 sprintf(name, "%s Playback Volume", ctlname);
11669 if (nid == 0x14) {
11670 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11671 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11672 HDA_OUTPUT));
11673 if (err < 0)
11674 return err;
11675 } else if (nid == 0x15) {
11676 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11677 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11678 HDA_OUTPUT));
11679 if (err < 0)
11680 return err;
11681 } else
11682 return -1;
11683 sprintf(name, "%s Playback Switch", ctlname);
11684 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11685 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11686 if (err < 0)
11687 return err;
11688 return 0;
11689}
11690
11691/* add playback controls from the parsed DAC table */
11692static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11693 const struct auto_pin_cfg *cfg)
11694{
11695 hda_nid_t nid;
11696 int err;
11697
11698 spec->multiout.num_dacs = 2; /* only use one dac */
11699 spec->multiout.dac_nids = spec->private_dac_nids;
11700 spec->multiout.dac_nids[0] = 2;
11701 spec->multiout.dac_nids[1] = 3;
11702
11703 nid = cfg->line_out_pins[0];
11704 if (nid)
ea1fb29a 11705 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
11706
11707 nid = cfg->speaker_pins[0];
11708 if (nid == 0x1d) {
11709 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11710 "Speaker Playback Volume",
11711 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11712 if (err < 0)
11713 return err;
11714 }
11715 nid = cfg->hp_pins[0];
11716 if (nid)
11717 alc268_new_analog_output(spec, nid, "Headphone", 0);
11718
11719 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11720 if (nid == 0x16) {
11721 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11722 "Mono Playback Switch",
11723 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11724 if (err < 0)
11725 return err;
11726 }
ea1fb29a 11727 return 0;
a361d84b
KY
11728}
11729
11730/* create playback/capture controls for input pins */
11731static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11732 const struct auto_pin_cfg *cfg)
11733{
61b9b9b1 11734 struct hda_input_mux *imux = &spec->private_imux[0];
a361d84b
KY
11735 int i, idx1;
11736
11737 for (i = 0; i < AUTO_PIN_LAST; i++) {
11738 switch(cfg->input_pins[i]) {
11739 case 0x18:
11740 idx1 = 0; /* Mic 1 */
11741 break;
11742 case 0x19:
11743 idx1 = 1; /* Mic 2 */
11744 break;
11745 case 0x1a:
11746 idx1 = 2; /* Line In */
11747 break;
ea1fb29a 11748 case 0x1c:
a361d84b
KY
11749 idx1 = 3; /* CD */
11750 break;
7194cae6
TI
11751 case 0x12:
11752 case 0x13:
11753 idx1 = 6; /* digital mics */
11754 break;
a361d84b
KY
11755 default:
11756 continue;
11757 }
11758 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11759 imux->items[imux->num_items].index = idx1;
ea1fb29a 11760 imux->num_items++;
a361d84b
KY
11761 }
11762 return 0;
11763}
11764
11765static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11766{
11767 struct alc_spec *spec = codec->spec;
11768 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11769 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11770 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11771 unsigned int dac_vol1, dac_vol2;
11772
11773 if (speaker_nid) {
11774 snd_hda_codec_write(codec, speaker_nid, 0,
11775 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11776 snd_hda_codec_write(codec, 0x0f, 0,
11777 AC_VERB_SET_AMP_GAIN_MUTE,
11778 AMP_IN_UNMUTE(1));
11779 snd_hda_codec_write(codec, 0x10, 0,
11780 AC_VERB_SET_AMP_GAIN_MUTE,
11781 AMP_IN_UNMUTE(1));
11782 } else {
11783 snd_hda_codec_write(codec, 0x0f, 0,
11784 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11785 snd_hda_codec_write(codec, 0x10, 0,
11786 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11787 }
11788
11789 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 11790 if (line_nid == 0x14)
a361d84b
KY
11791 dac_vol2 = AMP_OUT_ZERO;
11792 else if (line_nid == 0x15)
11793 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 11794 if (hp_nid == 0x14)
a361d84b
KY
11795 dac_vol2 = AMP_OUT_ZERO;
11796 else if (hp_nid == 0x15)
11797 dac_vol1 = AMP_OUT_ZERO;
11798 if (line_nid != 0x16 || hp_nid != 0x16 ||
11799 spec->autocfg.line_out_pins[1] != 0x16 ||
11800 spec->autocfg.line_out_pins[2] != 0x16)
11801 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11802
11803 snd_hda_codec_write(codec, 0x02, 0,
11804 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11805 snd_hda_codec_write(codec, 0x03, 0,
11806 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11807}
11808
11809/* pcm configuration: identiacal with ALC880 */
11810#define alc268_pcm_analog_playback alc880_pcm_analog_playback
11811#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 11812#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
11813#define alc268_pcm_digital_playback alc880_pcm_digital_playback
11814
11815/*
11816 * BIOS auto configuration
11817 */
11818static int alc268_parse_auto_config(struct hda_codec *codec)
11819{
11820 struct alc_spec *spec = codec->spec;
11821 int err;
11822 static hda_nid_t alc268_ignore[] = { 0 };
11823
11824 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11825 alc268_ignore);
11826 if (err < 0)
11827 return err;
7e0e44d4
TI
11828 if (!spec->autocfg.line_outs) {
11829 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11830 spec->multiout.max_channels = 2;
11831 spec->no_analog = 1;
11832 goto dig_only;
11833 }
a361d84b 11834 return 0; /* can't find valid BIOS pin config */
7e0e44d4 11835 }
a361d84b
KY
11836 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11837 if (err < 0)
11838 return err;
11839 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11840 if (err < 0)
11841 return err;
11842
11843 spec->multiout.max_channels = 2;
11844
7e0e44d4 11845 dig_only:
a361d84b 11846 /* digital only support output */
7e0e44d4 11847 if (spec->autocfg.dig_outs) {
a361d84b 11848 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
11849 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11850 }
603c4019 11851 if (spec->kctls.list)
d88897ea 11852 add_mixer(spec, spec->kctls.list);
a361d84b 11853
892981ff 11854 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 11855 add_mixer(spec, alc268_beep_mixer);
aef9d318 11856
d88897ea 11857 add_verb(spec, alc268_volume_init_verbs);
a361d84b 11858 spec->num_mux_defs = 1;
61b9b9b1 11859 spec->input_mux = &spec->private_imux[0];
a361d84b 11860
776e184e
TI
11861 err = alc_auto_add_mic_boost(codec);
11862 if (err < 0)
11863 return err;
11864
a361d84b
KY
11865 return 1;
11866}
11867
11868#define alc268_auto_init_multi_out alc882_auto_init_multi_out
11869#define alc268_auto_init_hp_out alc882_auto_init_hp_out
11870#define alc268_auto_init_analog_input alc882_auto_init_analog_input
11871
11872/* init callback for auto-configuration model -- overriding the default init */
11873static void alc268_auto_init(struct hda_codec *codec)
11874{
f6c7e546 11875 struct alc_spec *spec = codec->spec;
a361d84b
KY
11876 alc268_auto_init_multi_out(codec);
11877 alc268_auto_init_hp_out(codec);
11878 alc268_auto_init_mono_speaker_out(codec);
11879 alc268_auto_init_analog_input(codec);
f6c7e546 11880 if (spec->unsol_event)
7fb0d78f 11881 alc_inithook(codec);
a361d84b
KY
11882}
11883
11884/*
11885 * configuration and preset
11886 */
11887static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 11888 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 11889 [ALC268_3ST] = "3stack",
983f8ae4 11890 [ALC268_TOSHIBA] = "toshiba",
d273809e 11891 [ALC268_ACER] = "acer",
c238b4f4 11892 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 11893 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 11894 [ALC268_DELL] = "dell",
f12462c5 11895 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
11896#ifdef CONFIG_SND_DEBUG
11897 [ALC268_TEST] = "test",
11898#endif
a361d84b
KY
11899 [ALC268_AUTO] = "auto",
11900};
11901
11902static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 11903 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 11904 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 11905 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 11906 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 11907 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
11908 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11909 ALC268_ACER_ASPIRE_ONE),
3866f0b0 11910 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
57d13927 11911 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
ac3e3741 11912 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 11913 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 11914 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 11915 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
2346d0cd 11916 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
378bd6a5 11917 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 11918 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 11919 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
f12462c5 11920 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
11921 {}
11922};
11923
11924static struct alc_config_preset alc268_presets[] = {
eb5a6621 11925 [ALC267_QUANTA_IL1] = {
22971e3a 11926 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
eb5a6621
HRK
11927 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11928 alc267_quanta_il1_verbs },
11929 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11930 .dac_nids = alc268_dac_nids,
11931 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11932 .adc_nids = alc268_adc_nids_alt,
11933 .hp_nid = 0x03,
11934 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11935 .channel_mode = alc268_modes,
11936 .input_mux = &alc268_capture_source,
11937 .unsol_event = alc267_quanta_il1_unsol_event,
a9fd4f3f 11938 .init_hook = alc267_quanta_il1_init_hook,
eb5a6621 11939 },
a361d84b 11940 [ALC268_3ST] = {
aef9d318
TI
11941 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11942 alc268_beep_mixer },
a361d84b
KY
11943 .init_verbs = { alc268_base_init_verbs },
11944 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11945 .dac_nids = alc268_dac_nids,
11946 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11947 .adc_nids = alc268_adc_nids_alt,
e1406348 11948 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
11949 .hp_nid = 0x03,
11950 .dig_out_nid = ALC268_DIGOUT_NID,
11951 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11952 .channel_mode = alc268_modes,
11953 .input_mux = &alc268_capture_source,
11954 },
d1a991a6 11955 [ALC268_TOSHIBA] = {
42171c17 11956 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 11957 alc268_beep_mixer },
d273809e
TI
11958 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11959 alc268_toshiba_verbs },
d1a991a6
KY
11960 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11961 .dac_nids = alc268_dac_nids,
11962 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11963 .adc_nids = alc268_adc_nids_alt,
e1406348 11964 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
11965 .hp_nid = 0x03,
11966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11967 .channel_mode = alc268_modes,
11968 .input_mux = &alc268_capture_source,
d273809e 11969 .unsol_event = alc268_toshiba_unsol_event,
42171c17 11970 .init_hook = alc268_toshiba_init_hook,
d273809e
TI
11971 },
11972 [ALC268_ACER] = {
aef9d318
TI
11973 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11974 alc268_beep_mixer },
d273809e
TI
11975 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11976 alc268_acer_verbs },
11977 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11978 .dac_nids = alc268_dac_nids,
11979 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11980 .adc_nids = alc268_adc_nids_alt,
e1406348 11981 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
11982 .hp_nid = 0x02,
11983 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11984 .channel_mode = alc268_modes,
0ccb541c 11985 .input_mux = &alc268_acer_capture_source,
d273809e 11986 .unsol_event = alc268_acer_unsol_event,
889c4395 11987 .init_hook = alc268_acer_init_hook,
d1a991a6 11988 },
c238b4f4
TI
11989 [ALC268_ACER_DMIC] = {
11990 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11991 alc268_beep_mixer },
11992 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11993 alc268_acer_verbs },
11994 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11995 .dac_nids = alc268_dac_nids,
11996 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11997 .adc_nids = alc268_adc_nids_alt,
11998 .capsrc_nids = alc268_capsrc_nids,
11999 .hp_nid = 0x02,
12000 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12001 .channel_mode = alc268_modes,
12002 .input_mux = &alc268_acer_dmic_capture_source,
12003 .unsol_event = alc268_acer_unsol_event,
12004 .init_hook = alc268_acer_init_hook,
12005 },
8ef355da
KY
12006 [ALC268_ACER_ASPIRE_ONE] = {
12007 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a
TI
12008 alc268_beep_mixer,
12009 alc268_capture_alt_mixer },
8ef355da
KY
12010 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12011 alc268_acer_aspire_one_verbs },
12012 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12013 .dac_nids = alc268_dac_nids,
12014 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12015 .adc_nids = alc268_adc_nids_alt,
12016 .capsrc_nids = alc268_capsrc_nids,
12017 .hp_nid = 0x03,
12018 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12019 .channel_mode = alc268_modes,
12020 .input_mux = &alc268_acer_lc_capture_source,
12021 .unsol_event = alc268_acer_lc_unsol_event,
12022 .init_hook = alc268_acer_lc_init_hook,
12023 },
3866f0b0 12024 [ALC268_DELL] = {
aef9d318 12025 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
12026 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12027 alc268_dell_verbs },
12028 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12029 .dac_nids = alc268_dac_nids,
12030 .hp_nid = 0x02,
12031 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12032 .channel_mode = alc268_modes,
a9fd4f3f 12033 .unsol_event = alc_sku_unsol_event,
3866f0b0
TI
12034 .init_hook = alc268_dell_init_hook,
12035 .input_mux = &alc268_capture_source,
12036 },
f12462c5 12037 [ALC268_ZEPTO] = {
aef9d318
TI
12038 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12039 alc268_beep_mixer },
f12462c5
MT
12040 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12041 alc268_toshiba_verbs },
12042 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12043 .dac_nids = alc268_dac_nids,
12044 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12045 .adc_nids = alc268_adc_nids_alt,
e1406348 12046 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
12047 .hp_nid = 0x03,
12048 .dig_out_nid = ALC268_DIGOUT_NID,
12049 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12050 .channel_mode = alc268_modes,
12051 .input_mux = &alc268_capture_source,
12052 .unsol_event = alc268_toshiba_unsol_event,
42171c17 12053 .init_hook = alc268_toshiba_init_hook
f12462c5 12054 },
86c53bd2
JW
12055#ifdef CONFIG_SND_DEBUG
12056 [ALC268_TEST] = {
12057 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12058 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12059 alc268_volume_init_verbs },
12060 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12061 .dac_nids = alc268_dac_nids,
12062 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12063 .adc_nids = alc268_adc_nids_alt,
e1406348 12064 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
12065 .hp_nid = 0x03,
12066 .dig_out_nid = ALC268_DIGOUT_NID,
12067 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12068 .channel_mode = alc268_modes,
12069 .input_mux = &alc268_capture_source,
12070 },
12071#endif
a361d84b
KY
12072};
12073
12074static int patch_alc268(struct hda_codec *codec)
12075{
12076 struct alc_spec *spec;
12077 int board_config;
22971e3a 12078 int i, has_beep, err;
a361d84b
KY
12079
12080 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12081 if (spec == NULL)
12082 return -ENOMEM;
12083
12084 codec->spec = spec;
12085
12086 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12087 alc268_models,
12088 alc268_cfg_tbl);
12089
12090 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12091 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12092 "trying auto-probe from BIOS...\n");
12093 board_config = ALC268_AUTO;
12094 }
12095
12096 if (board_config == ALC268_AUTO) {
12097 /* automatic parse from the BIOS config */
12098 err = alc268_parse_auto_config(codec);
12099 if (err < 0) {
12100 alc_free(codec);
12101 return err;
12102 } else if (!err) {
12103 printk(KERN_INFO
12104 "hda_codec: Cannot set up configuration "
12105 "from BIOS. Using base mode...\n");
12106 board_config = ALC268_3ST;
12107 }
12108 }
12109
12110 if (board_config != ALC268_AUTO)
12111 setup_preset(spec, &alc268_presets[board_config]);
12112
2f893286
KY
12113 if (codec->vendor_id == 0x10ec0267) {
12114 spec->stream_name_analog = "ALC267 Analog";
12115 spec->stream_name_digital = "ALC267 Digital";
12116 } else {
12117 spec->stream_name_analog = "ALC268 Analog";
12118 spec->stream_name_digital = "ALC268 Digital";
12119 }
12120
a361d84b
KY
12121 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12122 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 12123 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 12124
a361d84b
KY
12125 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12126
22971e3a
TI
12127 has_beep = 0;
12128 for (i = 0; i < spec->num_mixers; i++) {
12129 if (spec->mixers[i] == alc268_beep_mixer) {
12130 has_beep = 1;
12131 break;
12132 }
12133 }
12134
12135 if (has_beep) {
12136 err = snd_hda_attach_beep_device(codec, 0x1);
12137 if (err < 0) {
12138 alc_free(codec);
12139 return err;
12140 }
12141 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12142 /* override the amp caps for beep generator */
12143 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
12144 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12145 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12146 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12147 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 12148 }
aef9d318 12149
7e0e44d4 12150 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
12151 /* check whether NID 0x07 is valid */
12152 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 12153 int i;
3866f0b0
TI
12154
12155 /* get type */
12156 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 12157 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
12158 spec->adc_nids = alc268_adc_nids_alt;
12159 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
d88897ea 12160 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
12161 } else {
12162 spec->adc_nids = alc268_adc_nids;
12163 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 12164 add_mixer(spec, alc268_capture_mixer);
a361d84b 12165 }
e1406348 12166 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
12167 /* set default input source */
12168 for (i = 0; i < spec->num_adc_nids; i++)
12169 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12170 0, AC_VERB_SET_CONNECT_SEL,
12171 spec->input_mux->items[0].index);
a361d84b 12172 }
2134ea4f
TI
12173
12174 spec->vmaster_nid = 0x02;
12175
a361d84b
KY
12176 codec->patch_ops = alc_patch_ops;
12177 if (board_config == ALC268_AUTO)
12178 spec->init_hook = alc268_auto_init;
ea1fb29a 12179
daead538
TI
12180 codec->proc_widget_hook = print_realtek_coef;
12181
a361d84b
KY
12182 return 0;
12183}
12184
f6a92248
KY
12185/*
12186 * ALC269 channel source setting (2 channel)
12187 */
12188#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12189
12190#define alc269_dac_nids alc260_dac_nids
12191
12192static hda_nid_t alc269_adc_nids[1] = {
12193 /* ADC1 */
f53281e6
KY
12194 0x08,
12195};
12196
e01bf509
TI
12197static hda_nid_t alc269_capsrc_nids[1] = {
12198 0x23,
12199};
12200
12201/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12202 * not a mux!
12203 */
12204
f53281e6
KY
12205static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12206 .num_items = 2,
12207 .items = {
12208 { "i-Mic", 0x5 },
12209 { "e-Mic", 0x0 },
12210 },
12211};
12212
12213static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12214 .num_items = 2,
12215 .items = {
12216 { "i-Mic", 0x1 },
12217 { "e-Mic", 0x0 },
12218 },
f6a92248
KY
12219};
12220
12221#define alc269_modes alc260_modes
12222#define alc269_capture_source alc880_lg_lw_capture_source
12223
12224static struct snd_kcontrol_new alc269_base_mixer[] = {
12225 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12226 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12227 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12228 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12231 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12232 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12233 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12234 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12236 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12237 { } /* end */
12238};
12239
60db6b53
KY
12240static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12241 /* output mixer control */
12242 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12243 {
12244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12245 .name = "Master Playback Switch",
12246 .info = snd_hda_mixer_amp_switch_info,
12247 .get = snd_hda_mixer_amp_switch_get,
12248 .put = alc268_acer_master_sw_put,
12249 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12250 },
12251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12252 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12253 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12254 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12255 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12256 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
12257 { }
12258};
12259
64154835
TV
12260static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12261 /* output mixer control */
12262 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12263 {
12264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12265 .name = "Master Playback Switch",
12266 .info = snd_hda_mixer_amp_switch_info,
12267 .get = snd_hda_mixer_amp_switch_get,
12268 .put = alc268_acer_master_sw_put,
12269 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12270 },
12271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12273 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12274 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12275 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12276 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12277 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12278 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12279 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
12280 { }
12281};
12282
f53281e6
KY
12283/* bind volumes of both NID 0x0c and 0x0d */
12284static struct hda_bind_ctls alc269_epc_bind_vol = {
12285 .ops = &snd_hda_bind_vol,
12286 .values = {
12287 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12288 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12289 0
12290 },
12291};
12292
12293static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12294 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12295 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12296 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12297 { } /* end */
12298};
12299
f53281e6
KY
12300/* capture mixer elements */
12301static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12302 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12303 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
12304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12305 { } /* end */
12306};
12307
12308/* FSC amilo */
12309static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12310 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12312 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
f53281e6
KY
12313 { } /* end */
12314};
12315
60db6b53
KY
12316static struct hda_verb alc269_quanta_fl1_verbs[] = {
12317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12318 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12319 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12321 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12322 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12323 { }
12324};
f6a92248 12325
64154835
TV
12326static struct hda_verb alc269_lifebook_verbs[] = {
12327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12328 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12332 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12333 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12334 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12335 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12336 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12337 { }
12338};
12339
60db6b53
KY
12340/* toggle speaker-output according to the hp-jack state */
12341static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12342{
12343 unsigned int present;
12344 unsigned char bits;
f6a92248 12345
60db6b53
KY
12346 present = snd_hda_codec_read(codec, 0x15, 0,
12347 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12348 bits = present ? AMP_IN_MUTE(0) : 0;
12349 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12350 AMP_IN_MUTE(0), bits);
12351 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12352 AMP_IN_MUTE(0), bits);
f6a92248 12353
60db6b53
KY
12354 snd_hda_codec_write(codec, 0x20, 0,
12355 AC_VERB_SET_COEF_INDEX, 0x0c);
12356 snd_hda_codec_write(codec, 0x20, 0,
12357 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 12358
60db6b53
KY
12359 snd_hda_codec_write(codec, 0x20, 0,
12360 AC_VERB_SET_COEF_INDEX, 0x0c);
12361 snd_hda_codec_write(codec, 0x20, 0,
12362 AC_VERB_SET_PROC_COEF, 0x480);
12363}
f6a92248 12364
64154835
TV
12365/* toggle speaker-output according to the hp-jacks state */
12366static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12367{
12368 unsigned int present;
12369 unsigned char bits;
12370
12371 /* Check laptop headphone socket */
12372 present = snd_hda_codec_read(codec, 0x15, 0,
12373 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12374
12375 /* Check port replicator headphone socket */
12376 present |= snd_hda_codec_read(codec, 0x1a, 0,
12377 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12378
12379 bits = present ? AMP_IN_MUTE(0) : 0;
12380 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12381 AMP_IN_MUTE(0), bits);
12382 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12383 AMP_IN_MUTE(0), bits);
12384
12385 snd_hda_codec_write(codec, 0x20, 0,
12386 AC_VERB_SET_COEF_INDEX, 0x0c);
12387 snd_hda_codec_write(codec, 0x20, 0,
12388 AC_VERB_SET_PROC_COEF, 0x680);
12389
12390 snd_hda_codec_write(codec, 0x20, 0,
12391 AC_VERB_SET_COEF_INDEX, 0x0c);
12392 snd_hda_codec_write(codec, 0x20, 0,
12393 AC_VERB_SET_PROC_COEF, 0x480);
12394}
12395
60db6b53
KY
12396static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12397{
12398 unsigned int present;
f6a92248 12399
60db6b53
KY
12400 present = snd_hda_codec_read(codec, 0x18, 0,
12401 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12402 snd_hda_codec_write(codec, 0x23, 0,
12403 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12404}
f6a92248 12405
64154835
TV
12406static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12407{
12408 unsigned int present_laptop;
12409 unsigned int present_dock;
12410
12411 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12413
12414 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12416
12417 /* Laptop mic port overrides dock mic port, design decision */
12418 if (present_dock)
12419 snd_hda_codec_write(codec, 0x23, 0,
12420 AC_VERB_SET_CONNECT_SEL, 0x3);
12421 if (present_laptop)
12422 snd_hda_codec_write(codec, 0x23, 0,
12423 AC_VERB_SET_CONNECT_SEL, 0x0);
12424 if (!present_dock && !present_laptop)
12425 snd_hda_codec_write(codec, 0x23, 0,
12426 AC_VERB_SET_CONNECT_SEL, 0x1);
12427}
12428
60db6b53
KY
12429static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12430 unsigned int res)
12431{
12432 if ((res >> 26) == ALC880_HP_EVENT)
12433 alc269_quanta_fl1_speaker_automute(codec);
12434 if ((res >> 26) == ALC880_MIC_EVENT)
12435 alc269_quanta_fl1_mic_automute(codec);
12436}
f6a92248 12437
64154835
TV
12438static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12439 unsigned int res)
12440{
12441 if ((res >> 26) == ALC880_HP_EVENT)
12442 alc269_lifebook_speaker_automute(codec);
12443 if ((res >> 26) == ALC880_MIC_EVENT)
12444 alc269_lifebook_mic_autoswitch(codec);
12445}
12446
60db6b53
KY
12447static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12448{
12449 alc269_quanta_fl1_speaker_automute(codec);
12450 alc269_quanta_fl1_mic_automute(codec);
12451}
f6a92248 12452
64154835
TV
12453static void alc269_lifebook_init_hook(struct hda_codec *codec)
12454{
12455 alc269_lifebook_speaker_automute(codec);
12456 alc269_lifebook_mic_autoswitch(codec);
12457}
12458
f53281e6
KY
12459static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12460 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12461 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12462 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12463 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12466 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12467 {}
12468};
12469
12470static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12471 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12472 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12473 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12474 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12475 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12476 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12477 {}
12478};
12479
12480/* toggle speaker-output according to the hp-jack state */
12481static void alc269_speaker_automute(struct hda_codec *codec)
12482{
12483 unsigned int present;
60db6b53 12484 unsigned char bits;
f53281e6
KY
12485
12486 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 12487 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
12488 bits = present ? AMP_IN_MUTE(0) : 0;
12489 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 12490 AMP_IN_MUTE(0), bits);
f53281e6 12491 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 12492 AMP_IN_MUTE(0), bits);
f53281e6
KY
12493}
12494
12495static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12496{
12497 unsigned int present;
12498
60db6b53
KY
12499 present = snd_hda_codec_read(codec, 0x18, 0,
12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12501 snd_hda_codec_write(codec, 0x23, 0,
12502 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
12503}
12504
12505static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12506{
12507 unsigned int present;
12508
60db6b53
KY
12509 present = snd_hda_codec_read(codec, 0x18, 0,
12510 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 12511 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12512 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 12513 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12514 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
12515}
12516
12517/* unsolicited event for HP jack sensing */
12518static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 12519 unsigned int res)
f53281e6
KY
12520{
12521 if ((res >> 26) == ALC880_HP_EVENT)
12522 alc269_speaker_automute(codec);
12523
12524 if ((res >> 26) == ALC880_MIC_EVENT)
12525 alc269_eeepc_dmic_automute(codec);
12526}
12527
12528static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12529{
12530 alc269_speaker_automute(codec);
12531 alc269_eeepc_dmic_automute(codec);
12532}
12533
12534/* unsolicited event for HP jack sensing */
12535static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 12536 unsigned int res)
f53281e6
KY
12537{
12538 if ((res >> 26) == ALC880_HP_EVENT)
12539 alc269_speaker_automute(codec);
12540
12541 if ((res >> 26) == ALC880_MIC_EVENT)
12542 alc269_eeepc_amic_automute(codec);
12543}
12544
12545static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12546{
12547 alc269_speaker_automute(codec);
12548 alc269_eeepc_amic_automute(codec);
12549}
12550
60db6b53
KY
12551/*
12552 * generic initialization of ADC, input mixers and output mixers
12553 */
12554static struct hda_verb alc269_init_verbs[] = {
12555 /*
12556 * Unmute ADC0 and set the default input to mic-in
12557 */
12558 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12559
12560 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12561 * analog-loopback mixer widget
12562 * Note: PASD motherboards uses the Line In 2 as the input for
12563 * front panel mic (mic 2)
12564 */
12565 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12568 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12569 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12570 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12571
12572 /*
12573 * Set up output mixers (0x0c - 0x0e)
12574 */
12575 /* set vol=0 to output mixers */
12576 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12577 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12578
12579 /* set up input amps for analog loopback */
12580 /* Amp Indices: DAC = 0, mixer = 1 */
12581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12587
12588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12590 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12591 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12592 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12593 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12594 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12595
12596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12597 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12600 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12602 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12603
12604 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12606
12607 /* FIXME: use matrix-type input source selection */
12608 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12609 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12614
12615 /* set EAPD */
12616 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12617 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12618 { }
12619};
12620
f6a92248
KY
12621/* add playback controls from the parsed DAC table */
12622static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12623 const struct auto_pin_cfg *cfg)
12624{
12625 hda_nid_t nid;
12626 int err;
12627
12628 spec->multiout.num_dacs = 1; /* only use one dac */
12629 spec->multiout.dac_nids = spec->private_dac_nids;
12630 spec->multiout.dac_nids[0] = 2;
12631
12632 nid = cfg->line_out_pins[0];
12633 if (nid) {
12634 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12635 "Front Playback Volume",
12636 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12637 if (err < 0)
12638 return err;
12639 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12640 "Front Playback Switch",
12641 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12642 if (err < 0)
12643 return err;
12644 }
12645
12646 nid = cfg->speaker_pins[0];
12647 if (nid) {
12648 if (!cfg->line_out_pins[0]) {
12649 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12650 "Speaker Playback Volume",
12651 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12652 HDA_OUTPUT));
12653 if (err < 0)
12654 return err;
12655 }
12656 if (nid == 0x16) {
12657 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12658 "Speaker Playback Switch",
12659 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12660 HDA_OUTPUT));
12661 if (err < 0)
12662 return err;
12663 } else {
12664 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12665 "Speaker Playback Switch",
12666 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12667 HDA_OUTPUT));
12668 if (err < 0)
12669 return err;
12670 }
12671 }
12672 nid = cfg->hp_pins[0];
12673 if (nid) {
12674 /* spec->multiout.hp_nid = 2; */
12675 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12676 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12677 "Headphone Playback Volume",
12678 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12679 HDA_OUTPUT));
12680 if (err < 0)
12681 return err;
12682 }
12683 if (nid == 0x16) {
12684 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12685 "Headphone Playback Switch",
12686 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12687 HDA_OUTPUT));
12688 if (err < 0)
12689 return err;
12690 } else {
12691 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12692 "Headphone Playback Switch",
12693 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12694 HDA_OUTPUT));
12695 if (err < 0)
12696 return err;
12697 }
12698 }
12699 return 0;
12700}
12701
ee956e09
TI
12702static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12703 const struct auto_pin_cfg *cfg)
12704{
12705 int err;
12706
12707 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12708 if (err < 0)
12709 return err;
12710 /* digital-mic input pin is excluded in alc880_auto_create..()
12711 * because it's under 0x18
12712 */
12713 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12714 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
61b9b9b1 12715 struct hda_input_mux *imux = &spec->private_imux[0];
ee956e09
TI
12716 imux->items[imux->num_items].label = "Int Mic";
12717 imux->items[imux->num_items].index = 0x05;
12718 imux->num_items++;
12719 }
12720 return 0;
12721}
f6a92248
KY
12722
12723#ifdef CONFIG_SND_HDA_POWER_SAVE
12724#define alc269_loopbacks alc880_loopbacks
12725#endif
12726
12727/* pcm configuration: identiacal with ALC880 */
12728#define alc269_pcm_analog_playback alc880_pcm_analog_playback
12729#define alc269_pcm_analog_capture alc880_pcm_analog_capture
12730#define alc269_pcm_digital_playback alc880_pcm_digital_playback
12731#define alc269_pcm_digital_capture alc880_pcm_digital_capture
12732
f03d3115
TI
12733static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12734 .substreams = 1,
12735 .channels_min = 2,
12736 .channels_max = 8,
12737 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12738 /* NID is set in alc_build_pcms */
12739 .ops = {
12740 .open = alc880_playback_pcm_open,
12741 .prepare = alc880_playback_pcm_prepare,
12742 .cleanup = alc880_playback_pcm_cleanup
12743 },
12744};
12745
12746static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12747 .substreams = 1,
12748 .channels_min = 2,
12749 .channels_max = 2,
12750 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12751 /* NID is set in alc_build_pcms */
12752};
12753
f6a92248
KY
12754/*
12755 * BIOS auto configuration
12756 */
12757static int alc269_parse_auto_config(struct hda_codec *codec)
12758{
12759 struct alc_spec *spec = codec->spec;
cfb9fb55 12760 int err;
f6a92248
KY
12761 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12762
12763 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12764 alc269_ignore);
12765 if (err < 0)
12766 return err;
12767
12768 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12769 if (err < 0)
12770 return err;
12771 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12772 if (err < 0)
12773 return err;
12774
12775 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12776
0852d7a6 12777 if (spec->autocfg.dig_outs)
f6a92248
KY
12778 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12779
603c4019 12780 if (spec->kctls.list)
d88897ea 12781 add_mixer(spec, spec->kctls.list);
f6a92248 12782
d88897ea 12783 add_verb(spec, alc269_init_verbs);
f6a92248 12784 spec->num_mux_defs = 1;
61b9b9b1 12785 spec->input_mux = &spec->private_imux[0];
e01bf509
TI
12786 /* set default input source */
12787 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12788 0, AC_VERB_SET_CONNECT_SEL,
12789 spec->input_mux->items[0].index);
f6a92248
KY
12790
12791 err = alc_auto_add_mic_boost(codec);
12792 if (err < 0)
12793 return err;
12794
7e0e44d4 12795 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 12796 set_capture_mixer(spec);
f53281e6 12797
f6a92248
KY
12798 return 1;
12799}
12800
12801#define alc269_auto_init_multi_out alc882_auto_init_multi_out
12802#define alc269_auto_init_hp_out alc882_auto_init_hp_out
12803#define alc269_auto_init_analog_input alc882_auto_init_analog_input
12804
12805
12806/* init callback for auto-configuration model -- overriding the default init */
12807static void alc269_auto_init(struct hda_codec *codec)
12808{
f6c7e546 12809 struct alc_spec *spec = codec->spec;
f6a92248
KY
12810 alc269_auto_init_multi_out(codec);
12811 alc269_auto_init_hp_out(codec);
12812 alc269_auto_init_analog_input(codec);
f6c7e546 12813 if (spec->unsol_event)
7fb0d78f 12814 alc_inithook(codec);
f6a92248
KY
12815}
12816
12817/*
12818 * configuration and preset
12819 */
12820static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 12821 [ALC269_BASIC] = "basic",
2922c9af
TI
12822 [ALC269_QUANTA_FL1] = "quanta",
12823 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
26f5df26 12824 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
64154835
TV
12825 [ALC269_FUJITSU] = "fujitsu",
12826 [ALC269_LIFEBOOK] = "lifebook"
f6a92248
KY
12827};
12828
12829static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 12830 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
12831 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12832 ALC269_ASUS_EEEPC_P703),
622e84cd
KY
12833 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12834 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12835 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12836 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12837 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12838 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
f53281e6
KY
12839 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12840 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
12841 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12842 ALC269_ASUS_EEEPC_P901),
622e84cd 12843 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
26f5df26 12844 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
64154835 12845 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
f6a92248
KY
12846 {}
12847};
12848
12849static struct alc_config_preset alc269_presets[] = {
12850 [ALC269_BASIC] = {
f9e336f6 12851 .mixers = { alc269_base_mixer },
f6a92248
KY
12852 .init_verbs = { alc269_init_verbs },
12853 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12854 .dac_nids = alc269_dac_nids,
12855 .hp_nid = 0x03,
12856 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12857 .channel_mode = alc269_modes,
12858 .input_mux = &alc269_capture_source,
12859 },
60db6b53
KY
12860 [ALC269_QUANTA_FL1] = {
12861 .mixers = { alc269_quanta_fl1_mixer },
12862 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12863 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12864 .dac_nids = alc269_dac_nids,
12865 .hp_nid = 0x03,
12866 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12867 .channel_mode = alc269_modes,
12868 .input_mux = &alc269_capture_source,
12869 .unsol_event = alc269_quanta_fl1_unsol_event,
12870 .init_hook = alc269_quanta_fl1_init_hook,
12871 },
f53281e6 12872 [ALC269_ASUS_EEEPC_P703] = {
f9e336f6
TI
12873 .mixers = { alc269_eeepc_mixer },
12874 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
12875 .init_verbs = { alc269_init_verbs,
12876 alc269_eeepc_amic_init_verbs },
12877 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12878 .dac_nids = alc269_dac_nids,
12879 .hp_nid = 0x03,
12880 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12881 .channel_mode = alc269_modes,
12882 .input_mux = &alc269_eeepc_amic_capture_source,
12883 .unsol_event = alc269_eeepc_amic_unsol_event,
12884 .init_hook = alc269_eeepc_amic_inithook,
12885 },
12886 [ALC269_ASUS_EEEPC_P901] = {
f9e336f6
TI
12887 .mixers = { alc269_eeepc_mixer },
12888 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
12889 .init_verbs = { alc269_init_verbs,
12890 alc269_eeepc_dmic_init_verbs },
12891 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12892 .dac_nids = alc269_dac_nids,
12893 .hp_nid = 0x03,
12894 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12895 .channel_mode = alc269_modes,
12896 .input_mux = &alc269_eeepc_dmic_capture_source,
12897 .unsol_event = alc269_eeepc_dmic_unsol_event,
12898 .init_hook = alc269_eeepc_dmic_inithook,
12899 },
26f5df26 12900 [ALC269_FUJITSU] = {
45bdd1c1 12901 .mixers = { alc269_fujitsu_mixer },
26f5df26
TI
12902 .cap_mixer = alc269_epc_capture_mixer,
12903 .init_verbs = { alc269_init_verbs,
12904 alc269_eeepc_dmic_init_verbs },
12905 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12906 .dac_nids = alc269_dac_nids,
12907 .hp_nid = 0x03,
12908 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12909 .channel_mode = alc269_modes,
12910 .input_mux = &alc269_eeepc_dmic_capture_source,
12911 .unsol_event = alc269_eeepc_dmic_unsol_event,
12912 .init_hook = alc269_eeepc_dmic_inithook,
12913 },
64154835
TV
12914 [ALC269_LIFEBOOK] = {
12915 .mixers = { alc269_lifebook_mixer },
12916 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12917 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12918 .dac_nids = alc269_dac_nids,
12919 .hp_nid = 0x03,
12920 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12921 .channel_mode = alc269_modes,
12922 .input_mux = &alc269_capture_source,
12923 .unsol_event = alc269_lifebook_unsol_event,
12924 .init_hook = alc269_lifebook_init_hook,
12925 },
f6a92248
KY
12926};
12927
12928static int patch_alc269(struct hda_codec *codec)
12929{
12930 struct alc_spec *spec;
12931 int board_config;
12932 int err;
12933
12934 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12935 if (spec == NULL)
12936 return -ENOMEM;
12937
12938 codec->spec = spec;
12939
2c3bf9ab
TI
12940 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12941
f6a92248
KY
12942 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12943 alc269_models,
12944 alc269_cfg_tbl);
12945
12946 if (board_config < 0) {
12947 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12948 "trying auto-probe from BIOS...\n");
12949 board_config = ALC269_AUTO;
12950 }
12951
12952 if (board_config == ALC269_AUTO) {
12953 /* automatic parse from the BIOS config */
12954 err = alc269_parse_auto_config(codec);
12955 if (err < 0) {
12956 alc_free(codec);
12957 return err;
12958 } else if (!err) {
12959 printk(KERN_INFO
12960 "hda_codec: Cannot set up configuration "
12961 "from BIOS. Using base mode...\n");
12962 board_config = ALC269_BASIC;
12963 }
12964 }
12965
680cd536
KK
12966 err = snd_hda_attach_beep_device(codec, 0x1);
12967 if (err < 0) {
12968 alc_free(codec);
12969 return err;
12970 }
12971
f6a92248
KY
12972 if (board_config != ALC269_AUTO)
12973 setup_preset(spec, &alc269_presets[board_config]);
12974
12975 spec->stream_name_analog = "ALC269 Analog";
f03d3115
TI
12976 if (codec->subsystem_id == 0x17aa3bf8) {
12977 /* Due to a hardware problem on Lenovo Ideadpad, we need to
12978 * fix the sample rate of analog I/O to 44.1kHz
12979 */
12980 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
12981 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
12982 } else {
12983 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12984 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12985 }
f6a92248
KY
12986 spec->stream_name_digital = "ALC269 Digital";
12987 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12988 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12989
12990 spec->adc_nids = alc269_adc_nids;
12991 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 12992 spec->capsrc_nids = alc269_capsrc_nids;
f9e336f6
TI
12993 if (!spec->cap_mixer)
12994 set_capture_mixer(spec);
45bdd1c1 12995 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248
KY
12996
12997 codec->patch_ops = alc_patch_ops;
12998 if (board_config == ALC269_AUTO)
12999 spec->init_hook = alc269_auto_init;
13000#ifdef CONFIG_SND_HDA_POWER_SAVE
13001 if (!spec->loopback.amplist)
13002 spec->loopback.amplist = alc269_loopbacks;
13003#endif
daead538 13004 codec->proc_widget_hook = print_realtek_coef;
f6a92248
KY
13005
13006 return 0;
13007}
13008
df694daa
KY
13009/*
13010 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13011 */
13012
13013/*
13014 * set the path ways for 2 channel output
13015 * need to set the codec line out and mic 1 pin widgets to inputs
13016 */
13017static struct hda_verb alc861_threestack_ch2_init[] = {
13018 /* set pin widget 1Ah (line in) for input */
13019 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13020 /* set pin widget 18h (mic1/2) for input, for mic also enable
13021 * the vref
13022 */
df694daa
KY
13023 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13024
9c7f852e
TI
13025 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13026#if 0
13027 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13028 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13029#endif
df694daa
KY
13030 { } /* end */
13031};
13032/*
13033 * 6ch mode
13034 * need to set the codec line out and mic 1 pin widgets to outputs
13035 */
13036static struct hda_verb alc861_threestack_ch6_init[] = {
13037 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13038 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13039 /* set pin widget 18h (mic1) for output (CLFE)*/
13040 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13041
13042 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 13043 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 13044
9c7f852e
TI
13045 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13046#if 0
13047 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13048 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13049#endif
df694daa
KY
13050 { } /* end */
13051};
13052
13053static struct hda_channel_mode alc861_threestack_modes[2] = {
13054 { 2, alc861_threestack_ch2_init },
13055 { 6, alc861_threestack_ch6_init },
13056};
22309c3e
TI
13057/* Set mic1 as input and unmute the mixer */
13058static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13059 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13060 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13061 { } /* end */
13062};
13063/* Set mic1 as output and mute mixer */
13064static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13065 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13066 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13067 { } /* end */
13068};
13069
13070static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13071 { 2, alc861_uniwill_m31_ch2_init },
13072 { 4, alc861_uniwill_m31_ch4_init },
13073};
df694daa 13074
7cdbff94
MD
13075/* Set mic1 and line-in as input and unmute the mixer */
13076static struct hda_verb alc861_asus_ch2_init[] = {
13077 /* set pin widget 1Ah (line in) for input */
13078 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13079 /* set pin widget 18h (mic1/2) for input, for mic also enable
13080 * the vref
13081 */
7cdbff94
MD
13082 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13083
13084 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13085#if 0
13086 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13087 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13088#endif
13089 { } /* end */
13090};
13091/* Set mic1 nad line-in as output and mute mixer */
13092static struct hda_verb alc861_asus_ch6_init[] = {
13093 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13094 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13095 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13096 /* set pin widget 18h (mic1) for output (CLFE)*/
13097 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13098 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13099 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13100 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13101
13102 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13103#if 0
13104 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13105 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13106#endif
13107 { } /* end */
13108};
13109
13110static struct hda_channel_mode alc861_asus_modes[2] = {
13111 { 2, alc861_asus_ch2_init },
13112 { 6, alc861_asus_ch6_init },
13113};
13114
df694daa
KY
13115/* patch-ALC861 */
13116
13117static struct snd_kcontrol_new alc861_base_mixer[] = {
13118 /* output mixer control */
13119 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13120 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13121 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13122 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13123 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13124
13125 /*Input mixer control */
13126 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13127 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13128 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13129 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13130 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13131 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13132 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13133 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13136
df694daa
KY
13137 { } /* end */
13138};
13139
13140static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13141 /* output mixer control */
13142 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13143 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13144 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13145 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13146 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13147
13148 /* Input mixer control */
13149 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13150 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13151 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13152 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13153 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13154 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13156 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13157 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13158 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13159
df694daa
KY
13160 {
13161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13162 .name = "Channel Mode",
13163 .info = alc_ch_mode_info,
13164 .get = alc_ch_mode_get,
13165 .put = alc_ch_mode_put,
13166 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13167 },
13168 { } /* end */
a53d1aec
TD
13169};
13170
d1d985f0 13171static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
13172 /* output mixer control */
13173 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13175 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 13176
a53d1aec 13177 { } /* end */
f12ab1e0 13178};
a53d1aec 13179
22309c3e
TI
13180static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13181 /* output mixer control */
13182 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13183 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13184 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13185 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13186 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13187
13188 /* Input mixer control */
13189 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13190 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13191 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13192 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13193 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13194 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13196 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13199
22309c3e
TI
13200 {
13201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13202 .name = "Channel Mode",
13203 .info = alc_ch_mode_info,
13204 .get = alc_ch_mode_get,
13205 .put = alc_ch_mode_put,
13206 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13207 },
13208 { } /* end */
f12ab1e0 13209};
7cdbff94
MD
13210
13211static struct snd_kcontrol_new alc861_asus_mixer[] = {
13212 /* output mixer control */
13213 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13214 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13215 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13216 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13217 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13218
13219 /* Input mixer control */
13220 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13221 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13222 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13223 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13224 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13225 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13226 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13227 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
13229 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13230
7cdbff94
MD
13231 {
13232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13233 .name = "Channel Mode",
13234 .info = alc_ch_mode_info,
13235 .get = alc_ch_mode_get,
13236 .put = alc_ch_mode_put,
13237 .private_value = ARRAY_SIZE(alc861_asus_modes),
13238 },
13239 { }
56bb0cab
TI
13240};
13241
13242/* additional mixer */
d1d985f0 13243static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
13244 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13245 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
13246 { }
13247};
7cdbff94 13248
df694daa
KY
13249/*
13250 * generic initialization of ADC, input mixers and output mixers
13251 */
13252static struct hda_verb alc861_base_init_verbs[] = {
13253 /*
13254 * Unmute ADC0 and set the default input to mic-in
13255 */
13256 /* port-A for surround (rear panel) */
13257 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13258 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13259 /* port-B for mic-in (rear panel) with vref */
13260 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13261 /* port-C for line-in (rear panel) */
13262 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13263 /* port-D for Front */
13264 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13265 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13266 /* port-E for HP out (front panel) */
13267 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13268 /* route front PCM to HP */
9dece1d7 13269 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13270 /* port-F for mic-in (front panel) with vref */
13271 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13272 /* port-G for CLFE (rear panel) */
13273 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13274 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13275 /* port-H for side (rear panel) */
13276 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13277 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13278 /* CD-in */
13279 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13280 /* route front mic to ADC1*/
13281 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13282 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13283
df694daa
KY
13284 /* Unmute DAC0~3 & spdif out*/
13285 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13286 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13287 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13288 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13289 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13290
df694daa
KY
13291 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13292 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13293 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13294 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13295 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13296
df694daa
KY
13297 /* Unmute Stereo Mixer 15 */
13298 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13299 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13302
13303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13304 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13305 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13306 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13308 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13309 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13311 /* hp used DAC 3 (Front) */
13312 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13314
13315 { }
13316};
13317
13318static struct hda_verb alc861_threestack_init_verbs[] = {
13319 /*
13320 * Unmute ADC0 and set the default input to mic-in
13321 */
13322 /* port-A for surround (rear panel) */
13323 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13324 /* port-B for mic-in (rear panel) with vref */
13325 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13326 /* port-C for line-in (rear panel) */
13327 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13328 /* port-D for Front */
13329 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13330 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13331 /* port-E for HP out (front panel) */
13332 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13333 /* route front PCM to HP */
9dece1d7 13334 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13335 /* port-F for mic-in (front panel) with vref */
13336 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13337 /* port-G for CLFE (rear panel) */
13338 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13339 /* port-H for side (rear panel) */
13340 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13341 /* CD-in */
13342 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13343 /* route front mic to ADC1*/
13344 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13346 /* Unmute DAC0~3 & spdif out*/
13347 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13348 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13349 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13350 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13351 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13352
df694daa
KY
13353 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13354 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13355 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13356 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13357 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13358
df694daa
KY
13359 /* Unmute Stereo Mixer 15 */
13360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13363 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13364
13365 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13367 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13368 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13370 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13371 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13372 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13373 /* hp used DAC 3 (Front) */
13374 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13375 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13376 { }
13377};
22309c3e
TI
13378
13379static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13380 /*
13381 * Unmute ADC0 and set the default input to mic-in
13382 */
13383 /* port-A for surround (rear panel) */
13384 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13385 /* port-B for mic-in (rear panel) with vref */
13386 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13387 /* port-C for line-in (rear panel) */
13388 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13389 /* port-D for Front */
13390 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13391 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13392 /* port-E for HP out (front panel) */
f12ab1e0
TI
13393 /* this has to be set to VREF80 */
13394 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 13395 /* route front PCM to HP */
9dece1d7 13396 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
13397 /* port-F for mic-in (front panel) with vref */
13398 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13399 /* port-G for CLFE (rear panel) */
13400 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13401 /* port-H for side (rear panel) */
13402 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13403 /* CD-in */
13404 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13405 /* route front mic to ADC1*/
13406 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13408 /* Unmute DAC0~3 & spdif out*/
13409 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13410 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13411 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13412 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13414
22309c3e
TI
13415 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13416 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13417 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13418 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13419 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13420
22309c3e
TI
13421 /* Unmute Stereo Mixer 15 */
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13425 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
13426
13427 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13428 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13429 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13430 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13435 /* hp used DAC 3 (Front) */
13436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
13437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13438 { }
13439};
13440
7cdbff94
MD
13441static struct hda_verb alc861_asus_init_verbs[] = {
13442 /*
13443 * Unmute ADC0 and set the default input to mic-in
13444 */
f12ab1e0
TI
13445 /* port-A for surround (rear panel)
13446 * according to codec#0 this is the HP jack
13447 */
7cdbff94
MD
13448 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13449 /* route front PCM to HP */
13450 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13451 /* port-B for mic-in (rear panel) with vref */
13452 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13453 /* port-C for line-in (rear panel) */
13454 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13455 /* port-D for Front */
13456 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13457 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13458 /* port-E for HP out (front panel) */
f12ab1e0
TI
13459 /* this has to be set to VREF80 */
13460 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 13461 /* route front PCM to HP */
9dece1d7 13462 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
13463 /* port-F for mic-in (front panel) with vref */
13464 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13465 /* port-G for CLFE (rear panel) */
13466 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13467 /* port-H for side (rear panel) */
13468 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13469 /* CD-in */
13470 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13471 /* route front mic to ADC1*/
13472 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13474 /* Unmute DAC0~3 & spdif out*/
13475 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13476 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13478 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13480 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13481 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13482 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13483 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13484 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13485
7cdbff94
MD
13486 /* Unmute Stereo Mixer 15 */
13487 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13491
13492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13494 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13498 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13500 /* hp used DAC 3 (Front) */
13501 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13503 { }
13504};
13505
56bb0cab
TI
13506/* additional init verbs for ASUS laptops */
13507static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13508 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13509 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13510 { }
13511};
7cdbff94 13512
df694daa
KY
13513/*
13514 * generic initialization of ADC, input mixers and output mixers
13515 */
13516static struct hda_verb alc861_auto_init_verbs[] = {
13517 /*
13518 * Unmute ADC0 and set the default input to mic-in
13519 */
f12ab1e0 13520 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13521 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13522
df694daa
KY
13523 /* Unmute DAC0~3 & spdif out*/
13524 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13525 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13527 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13529
df694daa
KY
13530 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13531 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13532 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13533 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13534 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13535
df694daa
KY
13536 /* Unmute Stereo Mixer 15 */
13537 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13541
13542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13544 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13545 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13546 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13548 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13549 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13550
13551 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13557 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13558 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 13559
f12ab1e0 13560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
13561
13562 { }
13563};
13564
a53d1aec
TD
13565static struct hda_verb alc861_toshiba_init_verbs[] = {
13566 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 13567
a53d1aec
TD
13568 { }
13569};
13570
13571/* toggle speaker-output according to the hp-jack state */
13572static void alc861_toshiba_automute(struct hda_codec *codec)
13573{
13574 unsigned int present;
13575
13576 present = snd_hda_codec_read(codec, 0x0f, 0,
13577 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13578 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13579 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13580 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13581 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
13582}
13583
13584static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13585 unsigned int res)
13586{
a53d1aec
TD
13587 if ((res >> 26) == ALC880_HP_EVENT)
13588 alc861_toshiba_automute(codec);
13589}
13590
df694daa
KY
13591/* pcm configuration: identiacal with ALC880 */
13592#define alc861_pcm_analog_playback alc880_pcm_analog_playback
13593#define alc861_pcm_analog_capture alc880_pcm_analog_capture
13594#define alc861_pcm_digital_playback alc880_pcm_digital_playback
13595#define alc861_pcm_digital_capture alc880_pcm_digital_capture
13596
13597
13598#define ALC861_DIGOUT_NID 0x07
13599
13600static struct hda_channel_mode alc861_8ch_modes[1] = {
13601 { 8, NULL }
13602};
13603
13604static hda_nid_t alc861_dac_nids[4] = {
13605 /* front, surround, clfe, side */
13606 0x03, 0x06, 0x05, 0x04
13607};
13608
9c7f852e
TI
13609static hda_nid_t alc660_dac_nids[3] = {
13610 /* front, clfe, surround */
13611 0x03, 0x05, 0x06
13612};
13613
df694daa
KY
13614static hda_nid_t alc861_adc_nids[1] = {
13615 /* ADC0-2 */
13616 0x08,
13617};
13618
13619static struct hda_input_mux alc861_capture_source = {
13620 .num_items = 5,
13621 .items = {
13622 { "Mic", 0x0 },
13623 { "Front Mic", 0x3 },
13624 { "Line", 0x1 },
13625 { "CD", 0x4 },
13626 { "Mixer", 0x5 },
13627 },
13628};
13629
13630/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
13631static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13632 const struct auto_pin_cfg *cfg)
df694daa
KY
13633{
13634 int i;
13635 hda_nid_t nid;
13636
13637 spec->multiout.dac_nids = spec->private_dac_nids;
13638 for (i = 0; i < cfg->line_outs; i++) {
13639 nid = cfg->line_out_pins[i];
13640 if (nid) {
13641 if (i >= ARRAY_SIZE(alc861_dac_nids))
13642 continue;
13643 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13644 }
13645 }
13646 spec->multiout.num_dacs = cfg->line_outs;
13647 return 0;
13648}
13649
13650/* add playback controls from the parsed DAC table */
13651static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13652 const struct auto_pin_cfg *cfg)
13653{
13654 char name[32];
f12ab1e0
TI
13655 static const char *chname[4] = {
13656 "Front", "Surround", NULL /*CLFE*/, "Side"
13657 };
df694daa
KY
13658 hda_nid_t nid;
13659 int i, idx, err;
13660
13661 for (i = 0; i < cfg->line_outs; i++) {
13662 nid = spec->multiout.dac_nids[i];
f12ab1e0 13663 if (!nid)
df694daa
KY
13664 continue;
13665 if (nid == 0x05) {
13666 /* Center/LFE */
f12ab1e0
TI
13667 err = add_control(spec, ALC_CTL_BIND_MUTE,
13668 "Center Playback Switch",
13669 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13670 HDA_OUTPUT));
13671 if (err < 0)
df694daa 13672 return err;
f12ab1e0
TI
13673 err = add_control(spec, ALC_CTL_BIND_MUTE,
13674 "LFE Playback Switch",
13675 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13676 HDA_OUTPUT));
13677 if (err < 0)
df694daa
KY
13678 return err;
13679 } else {
f12ab1e0
TI
13680 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13681 idx++)
df694daa
KY
13682 if (nid == alc861_dac_nids[idx])
13683 break;
13684 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
13685 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13686 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13687 HDA_OUTPUT));
13688 if (err < 0)
df694daa
KY
13689 return err;
13690 }
13691 }
13692 return 0;
13693}
13694
13695static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13696{
13697 int err;
13698 hda_nid_t nid;
13699
f12ab1e0 13700 if (!pin)
df694daa
KY
13701 return 0;
13702
13703 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13704 nid = 0x03;
f12ab1e0
TI
13705 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13706 "Headphone Playback Switch",
13707 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13708 if (err < 0)
df694daa
KY
13709 return err;
13710 spec->multiout.hp_nid = nid;
13711 }
13712 return 0;
13713}
13714
13715/* create playback/capture controls for input pins */
f12ab1e0
TI
13716static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13717 const struct auto_pin_cfg *cfg)
df694daa 13718{
61b9b9b1 13719 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
13720 int i, err, idx, idx1;
13721
13722 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 13723 switch (cfg->input_pins[i]) {
df694daa
KY
13724 case 0x0c:
13725 idx1 = 1;
f12ab1e0 13726 idx = 2; /* Line In */
df694daa
KY
13727 break;
13728 case 0x0f:
13729 idx1 = 2;
f12ab1e0 13730 idx = 2; /* Line In */
df694daa
KY
13731 break;
13732 case 0x0d:
13733 idx1 = 0;
f12ab1e0 13734 idx = 1; /* Mic In */
df694daa 13735 break;
f12ab1e0 13736 case 0x10:
df694daa 13737 idx1 = 3;
f12ab1e0 13738 idx = 1; /* Mic In */
df694daa
KY
13739 break;
13740 case 0x11:
13741 idx1 = 4;
f12ab1e0 13742 idx = 0; /* CD */
df694daa
KY
13743 break;
13744 default:
13745 continue;
13746 }
13747
4a471b7d
TI
13748 err = new_analog_input(spec, cfg->input_pins[i],
13749 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
13750 if (err < 0)
13751 return err;
13752
4a471b7d 13753 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 13754 imux->items[imux->num_items].index = idx1;
f12ab1e0 13755 imux->num_items++;
df694daa
KY
13756 }
13757 return 0;
13758}
13759
f12ab1e0
TI
13760static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13761 hda_nid_t nid,
df694daa
KY
13762 int pin_type, int dac_idx)
13763{
564c5bea
JL
13764 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13765 pin_type);
13766 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13767 AMP_OUT_UNMUTE);
df694daa
KY
13768}
13769
13770static void alc861_auto_init_multi_out(struct hda_codec *codec)
13771{
13772 struct alc_spec *spec = codec->spec;
13773 int i;
13774
13775 for (i = 0; i < spec->autocfg.line_outs; i++) {
13776 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13777 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 13778 if (nid)
baba8ee9 13779 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 13780 spec->multiout.dac_nids[i]);
df694daa
KY
13781 }
13782}
13783
13784static void alc861_auto_init_hp_out(struct hda_codec *codec)
13785{
13786 struct alc_spec *spec = codec->spec;
13787 hda_nid_t pin;
13788
eb06ed8f 13789 pin = spec->autocfg.hp_pins[0];
df694daa 13790 if (pin) /* connect to front */
f12ab1e0
TI
13791 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13792 spec->multiout.dac_nids[0]);
f6c7e546
TI
13793 pin = spec->autocfg.speaker_pins[0];
13794 if (pin)
13795 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
13796}
13797
13798static void alc861_auto_init_analog_input(struct hda_codec *codec)
13799{
13800 struct alc_spec *spec = codec->spec;
13801 int i;
13802
13803 for (i = 0; i < AUTO_PIN_LAST; i++) {
13804 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
13805 if (nid >= 0x0c && nid <= 0x11)
13806 alc_set_input_pin(codec, nid, i);
df694daa
KY
13807 }
13808}
13809
13810/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
13811/* return 1 if successful, 0 if the proper config is not found,
13812 * or a negative error code
13813 */
df694daa
KY
13814static int alc861_parse_auto_config(struct hda_codec *codec)
13815{
13816 struct alc_spec *spec = codec->spec;
13817 int err;
13818 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13819
f12ab1e0
TI
13820 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13821 alc861_ignore);
13822 if (err < 0)
df694daa 13823 return err;
f12ab1e0 13824 if (!spec->autocfg.line_outs)
df694daa
KY
13825 return 0; /* can't find valid BIOS pin config */
13826
f12ab1e0
TI
13827 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13828 if (err < 0)
13829 return err;
13830 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13831 if (err < 0)
13832 return err;
13833 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13834 if (err < 0)
13835 return err;
13836 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13837 if (err < 0)
df694daa
KY
13838 return err;
13839
13840 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13841
0852d7a6 13842 if (spec->autocfg.dig_outs)
df694daa
KY
13843 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13844
603c4019 13845 if (spec->kctls.list)
d88897ea 13846 add_mixer(spec, spec->kctls.list);
df694daa 13847
d88897ea 13848 add_verb(spec, alc861_auto_init_verbs);
df694daa 13849
a1e8d2da 13850 spec->num_mux_defs = 1;
61b9b9b1 13851 spec->input_mux = &spec->private_imux[0];
df694daa
KY
13852
13853 spec->adc_nids = alc861_adc_nids;
13854 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
f9e336f6 13855 set_capture_mixer(spec);
df694daa 13856
4a79ba34
TI
13857 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13858
df694daa
KY
13859 return 1;
13860}
13861
ae6b813a
TI
13862/* additional initialization for auto-configuration model */
13863static void alc861_auto_init(struct hda_codec *codec)
df694daa 13864{
f6c7e546 13865 struct alc_spec *spec = codec->spec;
df694daa
KY
13866 alc861_auto_init_multi_out(codec);
13867 alc861_auto_init_hp_out(codec);
13868 alc861_auto_init_analog_input(codec);
f6c7e546 13869 if (spec->unsol_event)
7fb0d78f 13870 alc_inithook(codec);
df694daa
KY
13871}
13872
cb53c626
TI
13873#ifdef CONFIG_SND_HDA_POWER_SAVE
13874static struct hda_amp_list alc861_loopbacks[] = {
13875 { 0x15, HDA_INPUT, 0 },
13876 { 0x15, HDA_INPUT, 1 },
13877 { 0x15, HDA_INPUT, 2 },
13878 { 0x15, HDA_INPUT, 3 },
13879 { } /* end */
13880};
13881#endif
13882
df694daa
KY
13883
13884/*
13885 * configuration and preset
13886 */
f5fcc13c
TI
13887static const char *alc861_models[ALC861_MODEL_LAST] = {
13888 [ALC861_3ST] = "3stack",
13889 [ALC660_3ST] = "3stack-660",
13890 [ALC861_3ST_DIG] = "3stack-dig",
13891 [ALC861_6ST_DIG] = "6stack-dig",
13892 [ALC861_UNIWILL_M31] = "uniwill-m31",
13893 [ALC861_TOSHIBA] = "toshiba",
13894 [ALC861_ASUS] = "asus",
13895 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13896 [ALC861_AUTO] = "auto",
13897};
13898
13899static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 13900 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
13901 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13902 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13903 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 13904 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 13905 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 13906 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
13907 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13908 * Any other models that need this preset?
13909 */
13910 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
13911 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13912 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 13913 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
13914 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13915 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13916 /* FIXME: the below seems conflict */
13917 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 13918 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 13919 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
13920 {}
13921};
13922
13923static struct alc_config_preset alc861_presets[] = {
13924 [ALC861_3ST] = {
13925 .mixers = { alc861_3ST_mixer },
13926 .init_verbs = { alc861_threestack_init_verbs },
13927 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13928 .dac_nids = alc861_dac_nids,
13929 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13930 .channel_mode = alc861_threestack_modes,
4e195a7b 13931 .need_dac_fix = 1,
df694daa
KY
13932 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13933 .adc_nids = alc861_adc_nids,
13934 .input_mux = &alc861_capture_source,
13935 },
13936 [ALC861_3ST_DIG] = {
13937 .mixers = { alc861_base_mixer },
13938 .init_verbs = { alc861_threestack_init_verbs },
13939 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13940 .dac_nids = alc861_dac_nids,
13941 .dig_out_nid = ALC861_DIGOUT_NID,
13942 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13943 .channel_mode = alc861_threestack_modes,
4e195a7b 13944 .need_dac_fix = 1,
df694daa
KY
13945 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13946 .adc_nids = alc861_adc_nids,
13947 .input_mux = &alc861_capture_source,
13948 },
13949 [ALC861_6ST_DIG] = {
13950 .mixers = { alc861_base_mixer },
13951 .init_verbs = { alc861_base_init_verbs },
13952 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13953 .dac_nids = alc861_dac_nids,
13954 .dig_out_nid = ALC861_DIGOUT_NID,
13955 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13956 .channel_mode = alc861_8ch_modes,
13957 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13958 .adc_nids = alc861_adc_nids,
13959 .input_mux = &alc861_capture_source,
13960 },
9c7f852e
TI
13961 [ALC660_3ST] = {
13962 .mixers = { alc861_3ST_mixer },
13963 .init_verbs = { alc861_threestack_init_verbs },
13964 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13965 .dac_nids = alc660_dac_nids,
13966 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13967 .channel_mode = alc861_threestack_modes,
4e195a7b 13968 .need_dac_fix = 1,
9c7f852e
TI
13969 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13970 .adc_nids = alc861_adc_nids,
13971 .input_mux = &alc861_capture_source,
13972 },
22309c3e
TI
13973 [ALC861_UNIWILL_M31] = {
13974 .mixers = { alc861_uniwill_m31_mixer },
13975 .init_verbs = { alc861_uniwill_m31_init_verbs },
13976 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13977 .dac_nids = alc861_dac_nids,
13978 .dig_out_nid = ALC861_DIGOUT_NID,
13979 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13980 .channel_mode = alc861_uniwill_m31_modes,
13981 .need_dac_fix = 1,
13982 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13983 .adc_nids = alc861_adc_nids,
13984 .input_mux = &alc861_capture_source,
13985 },
a53d1aec
TD
13986 [ALC861_TOSHIBA] = {
13987 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
13988 .init_verbs = { alc861_base_init_verbs,
13989 alc861_toshiba_init_verbs },
a53d1aec
TD
13990 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13991 .dac_nids = alc861_dac_nids,
13992 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13993 .channel_mode = alc883_3ST_2ch_modes,
13994 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13995 .adc_nids = alc861_adc_nids,
13996 .input_mux = &alc861_capture_source,
13997 .unsol_event = alc861_toshiba_unsol_event,
13998 .init_hook = alc861_toshiba_automute,
13999 },
7cdbff94
MD
14000 [ALC861_ASUS] = {
14001 .mixers = { alc861_asus_mixer },
14002 .init_verbs = { alc861_asus_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14004 .dac_nids = alc861_dac_nids,
14005 .dig_out_nid = ALC861_DIGOUT_NID,
14006 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14007 .channel_mode = alc861_asus_modes,
14008 .need_dac_fix = 1,
14009 .hp_nid = 0x06,
14010 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14011 .adc_nids = alc861_adc_nids,
14012 .input_mux = &alc861_capture_source,
14013 },
56bb0cab
TI
14014 [ALC861_ASUS_LAPTOP] = {
14015 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14016 .init_verbs = { alc861_asus_init_verbs,
14017 alc861_asus_laptop_init_verbs },
14018 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14019 .dac_nids = alc861_dac_nids,
14020 .dig_out_nid = ALC861_DIGOUT_NID,
14021 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14022 .channel_mode = alc883_3ST_2ch_modes,
14023 .need_dac_fix = 1,
14024 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14025 .adc_nids = alc861_adc_nids,
14026 .input_mux = &alc861_capture_source,
14027 },
14028};
df694daa
KY
14029
14030
14031static int patch_alc861(struct hda_codec *codec)
14032{
14033 struct alc_spec *spec;
14034 int board_config;
14035 int err;
14036
dc041e0b 14037 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
14038 if (spec == NULL)
14039 return -ENOMEM;
14040
f12ab1e0 14041 codec->spec = spec;
df694daa 14042
f5fcc13c
TI
14043 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14044 alc861_models,
14045 alc861_cfg_tbl);
9c7f852e 14046
f5fcc13c 14047 if (board_config < 0) {
9c7f852e
TI
14048 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14049 "trying auto-probe from BIOS...\n");
df694daa
KY
14050 board_config = ALC861_AUTO;
14051 }
14052
14053 if (board_config == ALC861_AUTO) {
14054 /* automatic parse from the BIOS config */
14055 err = alc861_parse_auto_config(codec);
14056 if (err < 0) {
14057 alc_free(codec);
14058 return err;
f12ab1e0 14059 } else if (!err) {
9c7f852e
TI
14060 printk(KERN_INFO
14061 "hda_codec: Cannot set up configuration "
14062 "from BIOS. Using base mode...\n");
df694daa
KY
14063 board_config = ALC861_3ST_DIG;
14064 }
14065 }
14066
680cd536
KK
14067 err = snd_hda_attach_beep_device(codec, 0x23);
14068 if (err < 0) {
14069 alc_free(codec);
14070 return err;
14071 }
14072
df694daa
KY
14073 if (board_config != ALC861_AUTO)
14074 setup_preset(spec, &alc861_presets[board_config]);
14075
14076 spec->stream_name_analog = "ALC861 Analog";
14077 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14078 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14079
14080 spec->stream_name_digital = "ALC861 Digital";
14081 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14082 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14083
45bdd1c1
TI
14084 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14085
2134ea4f
TI
14086 spec->vmaster_nid = 0x03;
14087
df694daa
KY
14088 codec->patch_ops = alc_patch_ops;
14089 if (board_config == ALC861_AUTO)
ae6b813a 14090 spec->init_hook = alc861_auto_init;
cb53c626
TI
14091#ifdef CONFIG_SND_HDA_POWER_SAVE
14092 if (!spec->loopback.amplist)
14093 spec->loopback.amplist = alc861_loopbacks;
14094#endif
daead538 14095 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 14096
1da177e4
LT
14097 return 0;
14098}
14099
f32610ed
JS
14100/*
14101 * ALC861-VD support
14102 *
14103 * Based on ALC882
14104 *
14105 * In addition, an independent DAC
14106 */
14107#define ALC861VD_DIGOUT_NID 0x06
14108
14109static hda_nid_t alc861vd_dac_nids[4] = {
14110 /* front, surr, clfe, side surr */
14111 0x02, 0x03, 0x04, 0x05
14112};
14113
14114/* dac_nids for ALC660vd are in a different order - according to
14115 * Realtek's driver.
14116 * This should probably tesult in a different mixer for 6stack models
14117 * of ALC660vd codecs, but for now there is only 3stack mixer
14118 * - and it is the same as in 861vd.
14119 * adc_nids in ALC660vd are (is) the same as in 861vd
14120 */
14121static hda_nid_t alc660vd_dac_nids[3] = {
14122 /* front, rear, clfe, rear_surr */
14123 0x02, 0x04, 0x03
14124};
14125
14126static hda_nid_t alc861vd_adc_nids[1] = {
14127 /* ADC0 */
14128 0x09,
14129};
14130
e1406348
TI
14131static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14132
f32610ed
JS
14133/* input MUX */
14134/* FIXME: should be a matrix-type input source selection */
14135static struct hda_input_mux alc861vd_capture_source = {
14136 .num_items = 4,
14137 .items = {
14138 { "Mic", 0x0 },
14139 { "Front Mic", 0x1 },
14140 { "Line", 0x2 },
14141 { "CD", 0x4 },
14142 },
14143};
14144
272a527c 14145static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 14146 .num_items = 2,
272a527c 14147 .items = {
b419f346
TD
14148 { "Ext Mic", 0x0 },
14149 { "Int Mic", 0x1 },
272a527c
KY
14150 },
14151};
14152
d1a991a6
KY
14153static struct hda_input_mux alc861vd_hp_capture_source = {
14154 .num_items = 2,
14155 .items = {
14156 { "Front Mic", 0x0 },
14157 { "ATAPI Mic", 0x1 },
14158 },
14159};
14160
f32610ed
JS
14161/*
14162 * 2ch mode
14163 */
14164static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14165 { 2, NULL }
14166};
14167
14168/*
14169 * 6ch mode
14170 */
14171static struct hda_verb alc861vd_6stack_ch6_init[] = {
14172 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14173 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14174 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14176 { } /* end */
14177};
14178
14179/*
14180 * 8ch mode
14181 */
14182static struct hda_verb alc861vd_6stack_ch8_init[] = {
14183 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14184 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14185 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14186 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14187 { } /* end */
14188};
14189
14190static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14191 { 6, alc861vd_6stack_ch6_init },
14192 { 8, alc861vd_6stack_ch8_init },
14193};
14194
14195static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14196 {
14197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14198 .name = "Channel Mode",
14199 .info = alc_ch_mode_info,
14200 .get = alc_ch_mode_get,
14201 .put = alc_ch_mode_put,
14202 },
14203 { } /* end */
14204};
14205
f32610ed
JS
14206/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14207 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14208 */
14209static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14210 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14212
14213 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14214 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14215
14216 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14217 HDA_OUTPUT),
14218 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14219 HDA_OUTPUT),
14220 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14221 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14222
14223 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14224 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14225
14226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14227
14228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14231
14232 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14233 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14234 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14235
14236 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14237 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14238
14239 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14240 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14241
f32610ed
JS
14242 { } /* end */
14243};
14244
14245static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14246 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14248
14249 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14250
14251 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14254
14255 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14256 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14257 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14258
14259 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14260 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14261
14262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14264
f32610ed
JS
14265 { } /* end */
14266};
14267
bdd148a3
KY
14268static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14269 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14270 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14271 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14272
14273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14274
14275 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14278
14279 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14280 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14281 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14282
14283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14285
14286 { } /* end */
14287};
14288
b419f346
TD
14289/* Pin assignment: Speaker=0x14, HP = 0x15,
14290 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
14291 */
14292static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
14293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14294 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
14295 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14296 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
14297 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14298 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14299 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14300 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14301 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14302 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
14303 { } /* end */
14304};
14305
d1a991a6
KY
14306/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14307 * Front Mic=0x18, ATAPI Mic = 0x19,
14308 */
14309static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14310 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14312 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14313 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14314 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14315 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14316 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14317 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 14318
d1a991a6
KY
14319 { } /* end */
14320};
14321
f32610ed
JS
14322/*
14323 * generic initialization of ADC, input mixers and output mixers
14324 */
14325static struct hda_verb alc861vd_volume_init_verbs[] = {
14326 /*
14327 * Unmute ADC0 and set the default input to mic-in
14328 */
14329 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14330 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14331
14332 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14333 * the analog-loopback mixer widget
14334 */
14335 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
14341
14342 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
14343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 14346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
14347
14348 /*
14349 * Set up output mixers (0x02 - 0x05)
14350 */
14351 /* set vol=0 to output mixers */
14352 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14353 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14354 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14355 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14356
14357 /* set up input amps for analog loopback */
14358 /* Amp Indices: DAC = 0, mixer = 1 */
14359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14362 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14364 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14366 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14367
14368 { }
14369};
14370
14371/*
14372 * 3-stack pin configuration:
14373 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14374 */
14375static struct hda_verb alc861vd_3stack_init_verbs[] = {
14376 /*
14377 * Set pin mode and muting
14378 */
14379 /* set front pin widgets 0x14 for output */
14380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14381 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14382 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14383
14384 /* Mic (rear) pin: input vref at 80% */
14385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14386 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14387 /* Front Mic pin: input vref at 80% */
14388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14390 /* Line In pin: input */
14391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14393 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14394 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14395 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14396 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14397 /* CD pin widget for input */
14398 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14399
14400 { }
14401};
14402
14403/*
14404 * 6-stack pin configuration:
14405 */
14406static struct hda_verb alc861vd_6stack_init_verbs[] = {
14407 /*
14408 * Set pin mode and muting
14409 */
14410 /* set front pin widgets 0x14 for output */
14411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14412 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14413 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14414
14415 /* Rear Pin: output 1 (0x0d) */
14416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14417 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14419 /* CLFE Pin: output 2 (0x0e) */
14420 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14421 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14422 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14423 /* Side Pin: output 3 (0x0f) */
14424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14425 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14426 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14427
14428 /* Mic (rear) pin: input vref at 80% */
14429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14431 /* Front Mic pin: input vref at 80% */
14432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14434 /* Line In pin: input */
14435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14437 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14439 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14440 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14441 /* CD pin widget for input */
14442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14443
14444 { }
14445};
14446
bdd148a3
KY
14447static struct hda_verb alc861vd_eapd_verbs[] = {
14448 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14449 { }
14450};
14451
f9423e7a
KY
14452static struct hda_verb alc660vd_eapd_verbs[] = {
14453 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14454 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14455 { }
14456};
14457
bdd148a3
KY
14458static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14461 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14462 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14463 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14464 {}
14465};
14466
bdd148a3
KY
14467static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14468{
14469 unsigned int present;
14470 unsigned char bits;
14471
14472 present = snd_hda_codec_read(codec, 0x18, 0,
14473 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14474 bits = present ? HDA_AMP_MUTE : 0;
14475 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14476 HDA_AMP_MUTE, bits);
bdd148a3
KY
14477}
14478
a9fd4f3f 14479static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
bdd148a3 14480{
a9fd4f3f
TI
14481 struct alc_spec *spec = codec->spec;
14482
14483 spec->autocfg.hp_pins[0] = 0x1b;
14484 spec->autocfg.speaker_pins[0] = 0x14;
14485 alc_automute_amp(codec);
bdd148a3
KY
14486 alc861vd_lenovo_mic_automute(codec);
14487}
14488
14489static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14490 unsigned int res)
14491{
14492 switch (res >> 26) {
bdd148a3
KY
14493 case ALC880_MIC_EVENT:
14494 alc861vd_lenovo_mic_automute(codec);
14495 break;
a9fd4f3f
TI
14496 default:
14497 alc_automute_amp_unsol_event(codec, res);
14498 break;
bdd148a3
KY
14499 }
14500}
14501
272a527c
KY
14502static struct hda_verb alc861vd_dallas_verbs[] = {
14503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14506 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14507
14508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14516
272a527c
KY
14517 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14518 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14521 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14522 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14523 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14524 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14525
14526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14528 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14530 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14532 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14533 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14534
14535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14539
14540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 14541 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
14542 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14543
14544 { } /* end */
14545};
14546
14547/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 14548static void alc861vd_dallas_init_hook(struct hda_codec *codec)
272a527c 14549{
a9fd4f3f 14550 struct alc_spec *spec = codec->spec;
272a527c 14551
a9fd4f3f
TI
14552 spec->autocfg.hp_pins[0] = 0x15;
14553 spec->autocfg.speaker_pins[0] = 0x14;
14554 alc_automute_amp(codec);
272a527c
KY
14555}
14556
cb53c626
TI
14557#ifdef CONFIG_SND_HDA_POWER_SAVE
14558#define alc861vd_loopbacks alc880_loopbacks
14559#endif
14560
f32610ed
JS
14561/* pcm configuration: identiacal with ALC880 */
14562#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14563#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14564#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14565#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14566
14567/*
14568 * configuration and preset
14569 */
14570static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14571 [ALC660VD_3ST] = "3stack-660",
983f8ae4 14572 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 14573 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
14574 [ALC861VD_3ST] = "3stack",
14575 [ALC861VD_3ST_DIG] = "3stack-digout",
14576 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 14577 [ALC861VD_LENOVO] = "lenovo",
272a527c 14578 [ALC861VD_DALLAS] = "dallas",
983f8ae4 14579 [ALC861VD_HP] = "hp",
f32610ed
JS
14580 [ALC861VD_AUTO] = "auto",
14581};
14582
14583static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
14584 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14585 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 14586 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 14587 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13c94744 14588 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 14589 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 14590 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 14591 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 14592 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 14593 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 14594 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 14595 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 14596 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 14597 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 14598 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
14599 {}
14600};
14601
14602static struct alc_config_preset alc861vd_presets[] = {
14603 [ALC660VD_3ST] = {
14604 .mixers = { alc861vd_3st_mixer },
14605 .init_verbs = { alc861vd_volume_init_verbs,
14606 alc861vd_3stack_init_verbs },
14607 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14608 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14609 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14610 .channel_mode = alc861vd_3stack_2ch_modes,
14611 .input_mux = &alc861vd_capture_source,
14612 },
6963f84c
MC
14613 [ALC660VD_3ST_DIG] = {
14614 .mixers = { alc861vd_3st_mixer },
14615 .init_verbs = { alc861vd_volume_init_verbs,
14616 alc861vd_3stack_init_verbs },
14617 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14618 .dac_nids = alc660vd_dac_nids,
14619 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14620 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14621 .channel_mode = alc861vd_3stack_2ch_modes,
14622 .input_mux = &alc861vd_capture_source,
14623 },
f32610ed
JS
14624 [ALC861VD_3ST] = {
14625 .mixers = { alc861vd_3st_mixer },
14626 .init_verbs = { alc861vd_volume_init_verbs,
14627 alc861vd_3stack_init_verbs },
14628 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14629 .dac_nids = alc861vd_dac_nids,
14630 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14631 .channel_mode = alc861vd_3stack_2ch_modes,
14632 .input_mux = &alc861vd_capture_source,
14633 },
14634 [ALC861VD_3ST_DIG] = {
14635 .mixers = { alc861vd_3st_mixer },
14636 .init_verbs = { alc861vd_volume_init_verbs,
14637 alc861vd_3stack_init_verbs },
14638 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14639 .dac_nids = alc861vd_dac_nids,
14640 .dig_out_nid = ALC861VD_DIGOUT_NID,
14641 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14642 .channel_mode = alc861vd_3stack_2ch_modes,
14643 .input_mux = &alc861vd_capture_source,
14644 },
14645 [ALC861VD_6ST_DIG] = {
14646 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14647 .init_verbs = { alc861vd_volume_init_verbs,
14648 alc861vd_6stack_init_verbs },
14649 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14650 .dac_nids = alc861vd_dac_nids,
14651 .dig_out_nid = ALC861VD_DIGOUT_NID,
14652 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14653 .channel_mode = alc861vd_6stack_modes,
14654 .input_mux = &alc861vd_capture_source,
14655 },
bdd148a3
KY
14656 [ALC861VD_LENOVO] = {
14657 .mixers = { alc861vd_lenovo_mixer },
14658 .init_verbs = { alc861vd_volume_init_verbs,
14659 alc861vd_3stack_init_verbs,
14660 alc861vd_eapd_verbs,
14661 alc861vd_lenovo_unsol_verbs },
14662 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14663 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14664 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14665 .channel_mode = alc861vd_3stack_2ch_modes,
14666 .input_mux = &alc861vd_capture_source,
14667 .unsol_event = alc861vd_lenovo_unsol_event,
a9fd4f3f 14668 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 14669 },
272a527c
KY
14670 [ALC861VD_DALLAS] = {
14671 .mixers = { alc861vd_dallas_mixer },
14672 .init_verbs = { alc861vd_dallas_verbs },
14673 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14674 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14675 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14676 .channel_mode = alc861vd_3stack_2ch_modes,
14677 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f
TI
14678 .unsol_event = alc_automute_amp_unsol_event,
14679 .init_hook = alc861vd_dallas_init_hook,
d1a991a6
KY
14680 },
14681 [ALC861VD_HP] = {
14682 .mixers = { alc861vd_hp_mixer },
14683 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14684 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14685 .dac_nids = alc861vd_dac_nids,
d1a991a6 14686 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
14687 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14688 .channel_mode = alc861vd_3stack_2ch_modes,
14689 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f
TI
14690 .unsol_event = alc_automute_amp_unsol_event,
14691 .init_hook = alc861vd_dallas_init_hook,
ea1fb29a 14692 },
13c94744
TI
14693 [ALC660VD_ASUS_V1S] = {
14694 .mixers = { alc861vd_lenovo_mixer },
14695 .init_verbs = { alc861vd_volume_init_verbs,
14696 alc861vd_3stack_init_verbs,
14697 alc861vd_eapd_verbs,
14698 alc861vd_lenovo_unsol_verbs },
14699 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14700 .dac_nids = alc660vd_dac_nids,
14701 .dig_out_nid = ALC861VD_DIGOUT_NID,
14702 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14703 .channel_mode = alc861vd_3stack_2ch_modes,
14704 .input_mux = &alc861vd_capture_source,
14705 .unsol_event = alc861vd_lenovo_unsol_event,
a9fd4f3f 14706 .init_hook = alc861vd_lenovo_init_hook,
13c94744 14707 },
f32610ed
JS
14708};
14709
14710/*
14711 * BIOS auto configuration
14712 */
14713static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14714 hda_nid_t nid, int pin_type, int dac_idx)
14715{
f6c7e546 14716 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
14717}
14718
14719static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14720{
14721 struct alc_spec *spec = codec->spec;
14722 int i;
14723
14724 for (i = 0; i <= HDA_SIDE; i++) {
14725 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14726 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
14727 if (nid)
14728 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 14729 pin_type, i);
f32610ed
JS
14730 }
14731}
14732
14733
14734static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14735{
14736 struct alc_spec *spec = codec->spec;
14737 hda_nid_t pin;
14738
14739 pin = spec->autocfg.hp_pins[0];
14740 if (pin) /* connect to front and use dac 0 */
14741 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14742 pin = spec->autocfg.speaker_pins[0];
14743 if (pin)
14744 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
14745}
14746
14747#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14748#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14749
14750static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14751{
14752 struct alc_spec *spec = codec->spec;
14753 int i;
14754
14755 for (i = 0; i < AUTO_PIN_LAST; i++) {
14756 hda_nid_t nid = spec->autocfg.input_pins[i];
14757 if (alc861vd_is_input_pin(nid)) {
23f0c048 14758 alc_set_input_pin(codec, nid, i);
e82c025b
TI
14759 if (nid != ALC861VD_PIN_CD_NID &&
14760 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
14761 snd_hda_codec_write(codec, nid, 0,
14762 AC_VERB_SET_AMP_GAIN_MUTE,
14763 AMP_OUT_MUTE);
14764 }
14765 }
14766}
14767
f511b01c
TI
14768#define alc861vd_auto_init_input_src alc882_auto_init_input_src
14769
f32610ed
JS
14770#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14771#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14772
14773/* add playback controls from the parsed DAC table */
14774/* Based on ALC880 version. But ALC861VD has separate,
14775 * different NIDs for mute/unmute switch and volume control */
14776static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14777 const struct auto_pin_cfg *cfg)
14778{
14779 char name[32];
14780 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14781 hda_nid_t nid_v, nid_s;
14782 int i, err;
14783
14784 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 14785 if (!spec->multiout.dac_nids[i])
f32610ed
JS
14786 continue;
14787 nid_v = alc861vd_idx_to_mixer_vol(
14788 alc880_dac_to_idx(
14789 spec->multiout.dac_nids[i]));
14790 nid_s = alc861vd_idx_to_mixer_switch(
14791 alc880_dac_to_idx(
14792 spec->multiout.dac_nids[i]));
14793
14794 if (i == 2) {
14795 /* Center/LFE */
f12ab1e0
TI
14796 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14797 "Center Playback Volume",
14798 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14799 HDA_OUTPUT));
14800 if (err < 0)
f32610ed 14801 return err;
f12ab1e0
TI
14802 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14803 "LFE Playback Volume",
14804 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14805 HDA_OUTPUT));
14806 if (err < 0)
f32610ed 14807 return err;
f12ab1e0
TI
14808 err = add_control(spec, ALC_CTL_BIND_MUTE,
14809 "Center Playback Switch",
14810 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14811 HDA_INPUT));
14812 if (err < 0)
f32610ed 14813 return err;
f12ab1e0
TI
14814 err = add_control(spec, ALC_CTL_BIND_MUTE,
14815 "LFE Playback Switch",
14816 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14817 HDA_INPUT));
14818 if (err < 0)
f32610ed
JS
14819 return err;
14820 } else {
14821 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
14822 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14823 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14824 HDA_OUTPUT));
14825 if (err < 0)
f32610ed
JS
14826 return err;
14827 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 14828 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 14829 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
14830 HDA_INPUT));
14831 if (err < 0)
f32610ed
JS
14832 return err;
14833 }
14834 }
14835 return 0;
14836}
14837
14838/* add playback controls for speaker and HP outputs */
14839/* Based on ALC880 version. But ALC861VD has separate,
14840 * different NIDs for mute/unmute switch and volume control */
14841static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14842 hda_nid_t pin, const char *pfx)
14843{
14844 hda_nid_t nid_v, nid_s;
14845 int err;
14846 char name[32];
14847
f12ab1e0 14848 if (!pin)
f32610ed
JS
14849 return 0;
14850
14851 if (alc880_is_fixed_pin(pin)) {
14852 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14853 /* specify the DAC as the extra output */
f12ab1e0 14854 if (!spec->multiout.hp_nid)
f32610ed
JS
14855 spec->multiout.hp_nid = nid_v;
14856 else
14857 spec->multiout.extra_out_nid[0] = nid_v;
14858 /* control HP volume/switch on the output mixer amp */
14859 nid_v = alc861vd_idx_to_mixer_vol(
14860 alc880_fixed_pin_idx(pin));
14861 nid_s = alc861vd_idx_to_mixer_switch(
14862 alc880_fixed_pin_idx(pin));
14863
14864 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
14865 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14866 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14867 if (err < 0)
f32610ed
JS
14868 return err;
14869 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14870 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14871 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14872 if (err < 0)
f32610ed
JS
14873 return err;
14874 } else if (alc880_is_multi_pin(pin)) {
14875 /* set manual connection */
14876 /* we have only a switch on HP-out PIN */
14877 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14878 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14879 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14880 if (err < 0)
f32610ed
JS
14881 return err;
14882 }
14883 return 0;
14884}
14885
14886/* parse the BIOS configuration and set up the alc_spec
14887 * return 1 if successful, 0 if the proper config is not found,
14888 * or a negative error code
14889 * Based on ALC880 version - had to change it to override
14890 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14891static int alc861vd_parse_auto_config(struct hda_codec *codec)
14892{
14893 struct alc_spec *spec = codec->spec;
14894 int err;
14895 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14896
f12ab1e0
TI
14897 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14898 alc861vd_ignore);
14899 if (err < 0)
f32610ed 14900 return err;
f12ab1e0 14901 if (!spec->autocfg.line_outs)
f32610ed
JS
14902 return 0; /* can't find valid BIOS pin config */
14903
f12ab1e0
TI
14904 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14905 if (err < 0)
14906 return err;
14907 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14908 if (err < 0)
14909 return err;
14910 err = alc861vd_auto_create_extra_out(spec,
14911 spec->autocfg.speaker_pins[0],
14912 "Speaker");
14913 if (err < 0)
14914 return err;
14915 err = alc861vd_auto_create_extra_out(spec,
14916 spec->autocfg.hp_pins[0],
14917 "Headphone");
14918 if (err < 0)
14919 return err;
14920 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14921 if (err < 0)
f32610ed
JS
14922 return err;
14923
14924 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14925
0852d7a6 14926 if (spec->autocfg.dig_outs)
f32610ed
JS
14927 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14928
603c4019 14929 if (spec->kctls.list)
d88897ea 14930 add_mixer(spec, spec->kctls.list);
f32610ed 14931
d88897ea 14932 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
14933
14934 spec->num_mux_defs = 1;
61b9b9b1 14935 spec->input_mux = &spec->private_imux[0];
f32610ed 14936
776e184e
TI
14937 err = alc_auto_add_mic_boost(codec);
14938 if (err < 0)
14939 return err;
14940
4a79ba34
TI
14941 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
14942
f32610ed
JS
14943 return 1;
14944}
14945
14946/* additional initialization for auto-configuration model */
14947static void alc861vd_auto_init(struct hda_codec *codec)
14948{
f6c7e546 14949 struct alc_spec *spec = codec->spec;
f32610ed
JS
14950 alc861vd_auto_init_multi_out(codec);
14951 alc861vd_auto_init_hp_out(codec);
14952 alc861vd_auto_init_analog_input(codec);
f511b01c 14953 alc861vd_auto_init_input_src(codec);
f6c7e546 14954 if (spec->unsol_event)
7fb0d78f 14955 alc_inithook(codec);
f32610ed
JS
14956}
14957
14958static int patch_alc861vd(struct hda_codec *codec)
14959{
14960 struct alc_spec *spec;
14961 int err, board_config;
14962
14963 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14964 if (spec == NULL)
14965 return -ENOMEM;
14966
14967 codec->spec = spec;
14968
14969 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14970 alc861vd_models,
14971 alc861vd_cfg_tbl);
14972
14973 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14974 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14975 "ALC861VD, trying auto-probe from BIOS...\n");
14976 board_config = ALC861VD_AUTO;
14977 }
14978
14979 if (board_config == ALC861VD_AUTO) {
14980 /* automatic parse from the BIOS config */
14981 err = alc861vd_parse_auto_config(codec);
14982 if (err < 0) {
14983 alc_free(codec);
14984 return err;
f12ab1e0 14985 } else if (!err) {
f32610ed
JS
14986 printk(KERN_INFO
14987 "hda_codec: Cannot set up configuration "
14988 "from BIOS. Using base mode...\n");
14989 board_config = ALC861VD_3ST;
14990 }
14991 }
14992
680cd536
KK
14993 err = snd_hda_attach_beep_device(codec, 0x23);
14994 if (err < 0) {
14995 alc_free(codec);
14996 return err;
14997 }
14998
f32610ed
JS
14999 if (board_config != ALC861VD_AUTO)
15000 setup_preset(spec, &alc861vd_presets[board_config]);
15001
2f893286
KY
15002 if (codec->vendor_id == 0x10ec0660) {
15003 spec->stream_name_analog = "ALC660-VD Analog";
15004 spec->stream_name_digital = "ALC660-VD Digital";
f9423e7a 15005 /* always turn on EAPD */
d88897ea 15006 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
15007 } else {
15008 spec->stream_name_analog = "ALC861VD Analog";
15009 spec->stream_name_digital = "ALC861VD Digital";
15010 }
15011
f32610ed
JS
15012 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15013 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15014
f32610ed
JS
15015 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15016 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15017
15018 spec->adc_nids = alc861vd_adc_nids;
15019 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 15020 spec->capsrc_nids = alc861vd_capsrc_nids;
61b9b9b1 15021 spec->capture_style = CAPT_MIX;
f32610ed 15022
f9e336f6 15023 set_capture_mixer(spec);
45bdd1c1 15024 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 15025
2134ea4f
TI
15026 spec->vmaster_nid = 0x02;
15027
f32610ed
JS
15028 codec->patch_ops = alc_patch_ops;
15029
15030 if (board_config == ALC861VD_AUTO)
15031 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
15032#ifdef CONFIG_SND_HDA_POWER_SAVE
15033 if (!spec->loopback.amplist)
15034 spec->loopback.amplist = alc861vd_loopbacks;
15035#endif
daead538 15036 codec->proc_widget_hook = print_realtek_coef;
f32610ed
JS
15037
15038 return 0;
15039}
15040
bc9f98a9
KY
15041/*
15042 * ALC662 support
15043 *
15044 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15045 * configuration. Each pin widget can choose any input DACs and a mixer.
15046 * Each ADC is connected from a mixer of all inputs. This makes possible
15047 * 6-channel independent captures.
15048 *
15049 * In addition, an independent DAC for the multi-playback (not used in this
15050 * driver yet).
15051 */
15052#define ALC662_DIGOUT_NID 0x06
15053#define ALC662_DIGIN_NID 0x0a
15054
15055static hda_nid_t alc662_dac_nids[4] = {
15056 /* front, rear, clfe, rear_surr */
15057 0x02, 0x03, 0x04
15058};
15059
622e84cd
KY
15060static hda_nid_t alc272_dac_nids[2] = {
15061 0x02, 0x03
15062};
15063
bc9f98a9
KY
15064static hda_nid_t alc662_adc_nids[1] = {
15065 /* ADC1-2 */
15066 0x09,
15067};
e1406348 15068
622e84cd
KY
15069static hda_nid_t alc272_adc_nids[1] = {
15070 /* ADC1-2 */
15071 0x08,
15072};
15073
77a261b7 15074static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
622e84cd
KY
15075static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15076
e1406348 15077
bc9f98a9
KY
15078/* input MUX */
15079/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
15080static struct hda_input_mux alc662_capture_source = {
15081 .num_items = 4,
15082 .items = {
15083 { "Mic", 0x0 },
15084 { "Front Mic", 0x1 },
15085 { "Line", 0x2 },
15086 { "CD", 0x4 },
15087 },
15088};
15089
15090static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15091 .num_items = 2,
15092 .items = {
15093 { "Mic", 0x1 },
15094 { "Line", 0x2 },
15095 },
15096};
291702f0
KY
15097
15098static struct hda_input_mux alc662_eeepc_capture_source = {
15099 .num_items = 2,
15100 .items = {
15101 { "i-Mic", 0x1 },
15102 { "e-Mic", 0x0 },
15103 },
15104};
15105
6dda9f4a
KY
15106static struct hda_input_mux alc663_capture_source = {
15107 .num_items = 3,
15108 .items = {
15109 { "Mic", 0x0 },
15110 { "Front Mic", 0x1 },
15111 { "Line", 0x2 },
15112 },
15113};
15114
15115static struct hda_input_mux alc663_m51va_capture_source = {
15116 .num_items = 2,
15117 .items = {
15118 { "Ext-Mic", 0x0 },
15119 { "D-Mic", 0x9 },
15120 },
15121};
15122
bc9f98a9
KY
15123/*
15124 * 2ch mode
15125 */
15126static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15127 { 2, NULL }
15128};
15129
15130/*
15131 * 2ch mode
15132 */
15133static struct hda_verb alc662_3ST_ch2_init[] = {
15134 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15135 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15136 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15137 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15138 { } /* end */
15139};
15140
15141/*
15142 * 6ch mode
15143 */
15144static struct hda_verb alc662_3ST_ch6_init[] = {
15145 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15146 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15147 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15150 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15151 { } /* end */
15152};
15153
15154static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15155 { 2, alc662_3ST_ch2_init },
15156 { 6, alc662_3ST_ch6_init },
15157};
15158
15159/*
15160 * 2ch mode
15161 */
15162static struct hda_verb alc662_sixstack_ch6_init[] = {
15163 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15164 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15165 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15166 { } /* end */
15167};
15168
15169/*
15170 * 6ch mode
15171 */
15172static struct hda_verb alc662_sixstack_ch8_init[] = {
15173 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15174 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15176 { } /* end */
15177};
15178
15179static struct hda_channel_mode alc662_5stack_modes[2] = {
15180 { 2, alc662_sixstack_ch6_init },
15181 { 6, alc662_sixstack_ch8_init },
15182};
15183
15184/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15185 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15186 */
15187
15188static struct snd_kcontrol_new alc662_base_mixer[] = {
15189 /* output mixer control */
15190 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 15191 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15192 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 15193 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15194 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15195 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15196 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15197 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15199
15200 /*Input mixer control */
15201 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15202 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15203 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15204 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15205 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15206 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15207 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
15209 { } /* end */
15210};
15211
15212static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15213 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15214 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
15215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15223 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15224 { } /* end */
15225};
15226
15227static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15228 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15229 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15230 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 15231 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15233 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15234 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15235 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15237 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15238 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15239 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15240 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15243 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15245 { } /* end */
15246};
15247
15248static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15249 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15250 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
15251 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15252 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
15253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15254 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15255 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15258 { } /* end */
15259};
15260
291702f0 15261static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
15262 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15263 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
15264
15265 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15266 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15267 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15268
15269 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15270 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15271 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15272 { } /* end */
15273};
15274
8c427226 15275static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
15276 ALC262_HIPPO_MASTER_SWITCH,
15277 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 15278 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
15279 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15280 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
15281 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15286 { } /* end */
15287};
15288
f1d4e28b
KY
15289static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15290 .ops = &snd_hda_bind_vol,
15291 .values = {
15292 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15293 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15294 0
15295 },
15296};
15297
15298static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15299 .ops = &snd_hda_bind_sw,
15300 .values = {
15301 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15302 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15303 0
15304 },
15305};
15306
6dda9f4a 15307static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
15308 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15309 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15311 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15312 { } /* end */
15313};
15314
15315static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15316 .ops = &snd_hda_bind_sw,
15317 .values = {
15318 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15319 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15320 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15321 0
15322 },
15323};
15324
15325static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15326 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15327 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15328 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15329 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15330 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15331 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15332
15333 { } /* end */
15334};
15335
15336static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15337 .ops = &snd_hda_bind_sw,
15338 .values = {
15339 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15340 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15341 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15342 0
15343 },
15344};
15345
15346static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15347 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15348 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15351 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15352 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15353 { } /* end */
15354};
15355
15356static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
15357 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15358 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
15359 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15362 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15363 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15364 { } /* end */
15365};
15366
15367static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15368 .ops = &snd_hda_bind_vol,
15369 .values = {
15370 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15371 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15372 0
15373 },
15374};
15375
15376static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15377 .ops = &snd_hda_bind_sw,
15378 .values = {
15379 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15380 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15381 0
15382 },
15383};
15384
15385static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15386 HDA_BIND_VOL("Master Playback Volume",
15387 &alc663_asus_two_bind_master_vol),
15388 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15389 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
15390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15392 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
15393 { } /* end */
15394};
15395
15396static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15397 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15398 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15401 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15402 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
15403 { } /* end */
15404};
15405
15406static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15407 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15409 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15412
15413 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15414 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15415 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15416 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15417 { } /* end */
15418};
15419
15420static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15421 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15422 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15423 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15424
15425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15427 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15428 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15431 { } /* end */
15432};
15433
bc9f98a9
KY
15434static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15435 {
15436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15437 .name = "Channel Mode",
15438 .info = alc_ch_mode_info,
15439 .get = alc_ch_mode_get,
15440 .put = alc_ch_mode_put,
15441 },
15442 { } /* end */
15443};
15444
15445static struct hda_verb alc662_init_verbs[] = {
15446 /* ADC: mute amp left and right */
15447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15448 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15449 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15450
cb53c626
TI
15451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15456
b60dd394
KY
15457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15463
15464 /* Front Pin: output 0 (0x0c) */
15465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15467
15468 /* Rear Pin: output 1 (0x0d) */
15469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15471
15472 /* CLFE Pin: output 2 (0x0e) */
15473 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15474 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15475
15476 /* Mic (rear) pin: input vref at 80% */
15477 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15478 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15479 /* Front Mic pin: input vref at 80% */
15480 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15482 /* Line In pin: input */
15483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15485 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15486 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15488 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15489 /* CD pin widget for input */
15490 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15491
15492 /* FIXME: use matrix-type input source selection */
15493 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15494 /* Input mixer */
15495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 15496 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
15497
15498 /* always trun on EAPD */
15499 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15500 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15501
bc9f98a9
KY
15502 { }
15503};
15504
15505static struct hda_verb alc662_sue_init_verbs[] = {
15506 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15507 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
15508 {}
15509};
15510
15511static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15512 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15513 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15514 {}
bc9f98a9
KY
15515};
15516
8c427226
KY
15517/* Set Unsolicited Event*/
15518static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15520 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15521 {}
15522};
15523
bc9f98a9
KY
15524/*
15525 * generic initialization of ADC, input mixers and output mixers
15526 */
15527static struct hda_verb alc662_auto_init_verbs[] = {
15528 /*
15529 * Unmute ADC and set the default input to mic-in
15530 */
15531 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15533
15534 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15535 * mixer widget
15536 * Note: PASD motherboards uses the Line In 2 as the input for front
15537 * panel mic (mic 2)
15538 */
15539 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
15545
15546 /*
15547 * Set up output mixers (0x0c - 0x0f)
15548 */
15549 /* set vol=0 to output mixers */
15550 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15551 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15552 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15553
15554 /* set up input amps for analog loopback */
15555 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
15556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15562
15563
15564 /* FIXME: use matrix-type input source selection */
15565 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15566 /* Input mixer */
15567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 15568 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
15569 { }
15570};
15571
24fb9173
TI
15572/* additional verbs for ALC663 */
15573static struct hda_verb alc663_auto_init_verbs[] = {
15574 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15575 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15576 { }
15577};
15578
6dda9f4a 15579static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
15580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
15582 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15583 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
15584 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15587 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15588 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15589 {}
15590};
15591
15592static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15593 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15594 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15595 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15599 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15600 {}
15601};
15602
15603static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15604 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15605 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15606 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15607 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15610 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15611 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15612 {}
15613};
6dda9f4a 15614
f1d4e28b
KY
15615static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15618 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15621 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15622 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15623 {}
15624};
6dda9f4a 15625
f1d4e28b
KY
15626static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15627 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15628 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15629 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15630 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15634 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15635 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15636 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15637 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15638 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15639 {}
15640};
15641
15642static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15643 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15644 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15645 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15646 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15647 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15652 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15653 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15654 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
15655 {}
15656};
15657
15658static struct hda_verb alc663_g71v_init_verbs[] = {
15659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15660 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15661 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15662
15663 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15664 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15665 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15666
15667 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15668 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15669 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15670 {}
15671};
15672
15673static struct hda_verb alc663_g50v_init_verbs[] = {
15674 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15675 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15676 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15677
15678 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15679 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15680 {}
15681};
15682
f1d4e28b
KY
15683static struct hda_verb alc662_ecs_init_verbs[] = {
15684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15685 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15686 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15687 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15688 {}
15689};
15690
622e84cd
KY
15691static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15692 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15693 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15694 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15695 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15696 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15697 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15701 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15702 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15703 {}
15704};
15705
15706static struct hda_verb alc272_dell_init_verbs[] = {
15707 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15708 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15710 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15711 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15712 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15713 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15714 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15715 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15716 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15717 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15718 {}
15719};
15720
f1d4e28b
KY
15721static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15722 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15723 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15724 { } /* end */
15725};
15726
622e84cd
KY
15727static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15728 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15729 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15730 { } /* end */
15731};
15732
bc9f98a9
KY
15733static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15734{
15735 unsigned int present;
f12ab1e0 15736 unsigned char bits;
bc9f98a9
KY
15737
15738 present = snd_hda_codec_read(codec, 0x14, 0,
15739 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15740 bits = present ? HDA_AMP_MUTE : 0;
15741 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15742 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15743}
15744
15745static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15746{
15747 unsigned int present;
f12ab1e0 15748 unsigned char bits;
bc9f98a9
KY
15749
15750 present = snd_hda_codec_read(codec, 0x1b, 0,
15751 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15752 bits = present ? HDA_AMP_MUTE : 0;
15753 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15754 HDA_AMP_MUTE, bits);
15755 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15756 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15757}
15758
15759static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15760 unsigned int res)
15761{
15762 if ((res >> 26) == ALC880_HP_EVENT)
15763 alc662_lenovo_101e_all_automute(codec);
15764 if ((res >> 26) == ALC880_FRONT_EVENT)
15765 alc662_lenovo_101e_ispeaker_automute(codec);
15766}
15767
291702f0
KY
15768static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15769{
15770 unsigned int present;
15771
15772 present = snd_hda_codec_read(codec, 0x18, 0,
15773 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15774 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15775 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15776 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15777 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15778 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15779 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15780 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15781 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15782}
15783
15784/* unsolicited event for HP jack sensing */
15785static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15786 unsigned int res)
15787{
291702f0
KY
15788 if ((res >> 26) == ALC880_MIC_EVENT)
15789 alc662_eeepc_mic_automute(codec);
42171c17
TI
15790 else
15791 alc262_hippo_unsol_event(codec, res);
291702f0
KY
15792}
15793
15794static void alc662_eeepc_inithook(struct hda_codec *codec)
15795{
42171c17 15796 alc262_hippo1_init_hook(codec);
291702f0
KY
15797 alc662_eeepc_mic_automute(codec);
15798}
15799
8c427226
KY
15800static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15801{
42171c17
TI
15802 struct alc_spec *spec = codec->spec;
15803
15804 spec->autocfg.hp_pins[0] = 0x14;
15805 spec->autocfg.speaker_pins[0] = 0x1b;
15806 alc262_hippo_master_update(codec);
8c427226
KY
15807}
15808
6dda9f4a
KY
15809static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15810{
15811 unsigned int present;
15812 unsigned char bits;
15813
15814 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
15815 AC_VERB_GET_PIN_SENSE, 0)
15816 & AC_PINSENSE_PRESENCE;
6dda9f4a 15817 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
15818 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15819 AMP_IN_MUTE(0), bits);
15820 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15821 AMP_IN_MUTE(0), bits);
15822}
15823
15824static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15825{
15826 unsigned int present;
15827 unsigned char bits;
15828
15829 present = snd_hda_codec_read(codec, 0x21, 0,
15830 AC_VERB_GET_PIN_SENSE, 0)
15831 & AC_PINSENSE_PRESENCE;
15832 bits = present ? HDA_AMP_MUTE : 0;
15833 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15834 AMP_IN_MUTE(0), bits);
15835 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15836 AMP_IN_MUTE(0), bits);
15837 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15838 AMP_IN_MUTE(0), bits);
15839 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15840 AMP_IN_MUTE(0), bits);
15841}
15842
15843static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15844{
15845 unsigned int present;
15846 unsigned char bits;
15847
15848 present = snd_hda_codec_read(codec, 0x15, 0,
15849 AC_VERB_GET_PIN_SENSE, 0)
15850 & AC_PINSENSE_PRESENCE;
15851 bits = present ? HDA_AMP_MUTE : 0;
15852 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15853 AMP_IN_MUTE(0), bits);
15854 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15855 AMP_IN_MUTE(0), bits);
15856 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15857 AMP_IN_MUTE(0), bits);
15858 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15859 AMP_IN_MUTE(0), bits);
15860}
15861
15862static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15863{
15864 unsigned int present;
15865 unsigned char bits;
15866
15867 present = snd_hda_codec_read(codec, 0x1b, 0,
15868 AC_VERB_GET_PIN_SENSE, 0)
15869 & AC_PINSENSE_PRESENCE;
15870 bits = present ? 0 : PIN_OUT;
15871 snd_hda_codec_write(codec, 0x14, 0,
15872 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15873}
15874
15875static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15876{
15877 unsigned int present1, present2;
15878
15879 present1 = snd_hda_codec_read(codec, 0x21, 0,
15880 AC_VERB_GET_PIN_SENSE, 0)
15881 & AC_PINSENSE_PRESENCE;
15882 present2 = snd_hda_codec_read(codec, 0x15, 0,
15883 AC_VERB_GET_PIN_SENSE, 0)
15884 & AC_PINSENSE_PRESENCE;
15885
15886 if (present1 || present2) {
15887 snd_hda_codec_write_cache(codec, 0x14, 0,
15888 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15889 } else {
15890 snd_hda_codec_write_cache(codec, 0x14, 0,
15891 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15892 }
15893}
15894
15895static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15896{
15897 unsigned int present1, present2;
15898
15899 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15900 AC_VERB_GET_PIN_SENSE, 0)
15901 & AC_PINSENSE_PRESENCE;
15902 present2 = snd_hda_codec_read(codec, 0x15, 0,
15903 AC_VERB_GET_PIN_SENSE, 0)
15904 & AC_PINSENSE_PRESENCE;
15905
15906 if (present1 || present2) {
15907 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15908 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15909 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15910 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15911 } else {
15912 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15913 AMP_IN_MUTE(0), 0);
15914 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15915 AMP_IN_MUTE(0), 0);
15916 }
6dda9f4a
KY
15917}
15918
15919static void alc663_m51va_mic_automute(struct hda_codec *codec)
15920{
15921 unsigned int present;
15922
15923 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
15924 AC_VERB_GET_PIN_SENSE, 0)
15925 & AC_PINSENSE_PRESENCE;
6dda9f4a 15926 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15927 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15928 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15929 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15930 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15931 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 15932 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15933 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
15934}
15935
15936static void alc663_m51va_unsol_event(struct hda_codec *codec,
15937 unsigned int res)
15938{
15939 switch (res >> 26) {
15940 case ALC880_HP_EVENT:
15941 alc663_m51va_speaker_automute(codec);
15942 break;
15943 case ALC880_MIC_EVENT:
15944 alc663_m51va_mic_automute(codec);
15945 break;
15946 }
15947}
15948
15949static void alc663_m51va_inithook(struct hda_codec *codec)
15950{
15951 alc663_m51va_speaker_automute(codec);
15952 alc663_m51va_mic_automute(codec);
15953}
15954
f1d4e28b
KY
15955/* ***************** Mode1 ******************************/
15956static void alc663_mode1_unsol_event(struct hda_codec *codec,
15957 unsigned int res)
15958{
15959 switch (res >> 26) {
15960 case ALC880_HP_EVENT:
15961 alc663_m51va_speaker_automute(codec);
15962 break;
15963 case ALC880_MIC_EVENT:
15964 alc662_eeepc_mic_automute(codec);
15965 break;
15966 }
15967}
15968
15969static void alc663_mode1_inithook(struct hda_codec *codec)
15970{
15971 alc663_m51va_speaker_automute(codec);
15972 alc662_eeepc_mic_automute(codec);
15973}
15974/* ***************** Mode2 ******************************/
15975static void alc662_mode2_unsol_event(struct hda_codec *codec,
15976 unsigned int res)
15977{
15978 switch (res >> 26) {
15979 case ALC880_HP_EVENT:
15980 alc662_f5z_speaker_automute(codec);
15981 break;
15982 case ALC880_MIC_EVENT:
15983 alc662_eeepc_mic_automute(codec);
15984 break;
15985 }
15986}
15987
15988static void alc662_mode2_inithook(struct hda_codec *codec)
15989{
15990 alc662_f5z_speaker_automute(codec);
15991 alc662_eeepc_mic_automute(codec);
15992}
15993/* ***************** Mode3 ******************************/
15994static void alc663_mode3_unsol_event(struct hda_codec *codec,
15995 unsigned int res)
15996{
15997 switch (res >> 26) {
15998 case ALC880_HP_EVENT:
15999 alc663_two_hp_m1_speaker_automute(codec);
16000 break;
16001 case ALC880_MIC_EVENT:
16002 alc662_eeepc_mic_automute(codec);
16003 break;
16004 }
16005}
16006
16007static void alc663_mode3_inithook(struct hda_codec *codec)
16008{
16009 alc663_two_hp_m1_speaker_automute(codec);
16010 alc662_eeepc_mic_automute(codec);
16011}
16012/* ***************** Mode4 ******************************/
16013static void alc663_mode4_unsol_event(struct hda_codec *codec,
16014 unsigned int res)
16015{
16016 switch (res >> 26) {
16017 case ALC880_HP_EVENT:
16018 alc663_21jd_two_speaker_automute(codec);
16019 break;
16020 case ALC880_MIC_EVENT:
16021 alc662_eeepc_mic_automute(codec);
16022 break;
16023 }
16024}
16025
16026static void alc663_mode4_inithook(struct hda_codec *codec)
16027{
16028 alc663_21jd_two_speaker_automute(codec);
16029 alc662_eeepc_mic_automute(codec);
16030}
16031/* ***************** Mode5 ******************************/
16032static void alc663_mode5_unsol_event(struct hda_codec *codec,
16033 unsigned int res)
16034{
16035 switch (res >> 26) {
16036 case ALC880_HP_EVENT:
16037 alc663_15jd_two_speaker_automute(codec);
16038 break;
16039 case ALC880_MIC_EVENT:
16040 alc662_eeepc_mic_automute(codec);
16041 break;
16042 }
16043}
16044
16045static void alc663_mode5_inithook(struct hda_codec *codec)
16046{
16047 alc663_15jd_two_speaker_automute(codec);
16048 alc662_eeepc_mic_automute(codec);
16049}
16050/* ***************** Mode6 ******************************/
16051static void alc663_mode6_unsol_event(struct hda_codec *codec,
16052 unsigned int res)
16053{
16054 switch (res >> 26) {
16055 case ALC880_HP_EVENT:
16056 alc663_two_hp_m2_speaker_automute(codec);
16057 break;
16058 case ALC880_MIC_EVENT:
16059 alc662_eeepc_mic_automute(codec);
16060 break;
16061 }
16062}
16063
16064static void alc663_mode6_inithook(struct hda_codec *codec)
16065{
16066 alc663_two_hp_m2_speaker_automute(codec);
16067 alc662_eeepc_mic_automute(codec);
16068}
16069
6dda9f4a
KY
16070static void alc663_g71v_hp_automute(struct hda_codec *codec)
16071{
16072 unsigned int present;
16073 unsigned char bits;
16074
16075 present = snd_hda_codec_read(codec, 0x21, 0,
16076 AC_VERB_GET_PIN_SENSE, 0)
16077 & AC_PINSENSE_PRESENCE;
16078 bits = present ? HDA_AMP_MUTE : 0;
16079 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16080 HDA_AMP_MUTE, bits);
16081 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16082 HDA_AMP_MUTE, bits);
16083}
16084
16085static void alc663_g71v_front_automute(struct hda_codec *codec)
16086{
16087 unsigned int present;
16088 unsigned char bits;
16089
16090 present = snd_hda_codec_read(codec, 0x15, 0,
16091 AC_VERB_GET_PIN_SENSE, 0)
16092 & AC_PINSENSE_PRESENCE;
16093 bits = present ? HDA_AMP_MUTE : 0;
16094 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16095 HDA_AMP_MUTE, bits);
16096}
16097
16098static void alc663_g71v_unsol_event(struct hda_codec *codec,
16099 unsigned int res)
16100{
16101 switch (res >> 26) {
16102 case ALC880_HP_EVENT:
16103 alc663_g71v_hp_automute(codec);
16104 break;
16105 case ALC880_FRONT_EVENT:
16106 alc663_g71v_front_automute(codec);
16107 break;
16108 case ALC880_MIC_EVENT:
16109 alc662_eeepc_mic_automute(codec);
16110 break;
16111 }
16112}
16113
16114static void alc663_g71v_inithook(struct hda_codec *codec)
16115{
16116 alc663_g71v_front_automute(codec);
16117 alc663_g71v_hp_automute(codec);
16118 alc662_eeepc_mic_automute(codec);
16119}
16120
16121static void alc663_g50v_unsol_event(struct hda_codec *codec,
16122 unsigned int res)
16123{
16124 switch (res >> 26) {
16125 case ALC880_HP_EVENT:
16126 alc663_m51va_speaker_automute(codec);
16127 break;
16128 case ALC880_MIC_EVENT:
16129 alc662_eeepc_mic_automute(codec);
16130 break;
16131 }
16132}
16133
16134static void alc663_g50v_inithook(struct hda_codec *codec)
16135{
16136 alc663_m51va_speaker_automute(codec);
16137 alc662_eeepc_mic_automute(codec);
16138}
16139
f1d4e28b
KY
16140static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16141 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 16142 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
16143
16144 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16145 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16146 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16147
16148 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16149 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16150 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16151 { } /* end */
16152};
16153
cb53c626
TI
16154#ifdef CONFIG_SND_HDA_POWER_SAVE
16155#define alc662_loopbacks alc880_loopbacks
16156#endif
16157
bc9f98a9
KY
16158
16159/* pcm configuration: identiacal with ALC880 */
16160#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16161#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16162#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16163#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16164
16165/*
16166 * configuration and preset
16167 */
16168static const char *alc662_models[ALC662_MODEL_LAST] = {
16169 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16170 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16171 [ALC662_3ST_6ch] = "3stack-6ch",
16172 [ALC662_5ST_DIG] = "6stack-dig",
16173 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 16174 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 16175 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 16176 [ALC662_ECS] = "ecs",
6dda9f4a
KY
16177 [ALC663_ASUS_M51VA] = "m51va",
16178 [ALC663_ASUS_G71V] = "g71v",
16179 [ALC663_ASUS_H13] = "h13",
16180 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
16181 [ALC663_ASUS_MODE1] = "asus-mode1",
16182 [ALC662_ASUS_MODE2] = "asus-mode2",
16183 [ALC663_ASUS_MODE3] = "asus-mode3",
16184 [ALC663_ASUS_MODE4] = "asus-mode4",
16185 [ALC663_ASUS_MODE5] = "asus-mode5",
16186 [ALC663_ASUS_MODE6] = "asus-mode6",
bc9f98a9
KY
16187 [ALC662_AUTO] = "auto",
16188};
16189
16190static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 16191 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
16192 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16193 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 16194 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509
TI
16195 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16196 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 16197 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 16198 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 16199 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16200 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16201 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16202 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16203 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16204 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16205 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd
KY
16206 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16207 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16208 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 16209 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16210 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16211 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16212 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 16213 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 16214 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16215 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16216 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16217 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 16218 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 16219 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd
KY
16220 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16221 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16222 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
16223 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16224 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16225 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 16226 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
16227 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16228 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 16229 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
16230 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16231 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16232 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16233 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16234 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 16235 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 16236 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16237 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
16238 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16239 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16240 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16241 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
16242 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16243 ALC662_3ST_6ch_DIG),
cb55974c
HRK
16244 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16245 ALC662_3ST_6ch_DIG),
19c009aa 16246 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 16247 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 16248 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 16249 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 16250 ALC662_3ST_6ch_DIG),
dea0a509
TI
16251 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16252 ALC663_ASUS_H13),
bc9f98a9
KY
16253 {}
16254};
16255
16256static struct alc_config_preset alc662_presets[] = {
16257 [ALC662_3ST_2ch_DIG] = {
f9e336f6 16258 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
16259 .init_verbs = { alc662_init_verbs },
16260 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16261 .dac_nids = alc662_dac_nids,
16262 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16263 .dig_in_nid = ALC662_DIGIN_NID,
16264 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16265 .channel_mode = alc662_3ST_2ch_modes,
16266 .input_mux = &alc662_capture_source,
16267 },
16268 [ALC662_3ST_6ch_DIG] = {
f9e336f6 16269 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16270 .init_verbs = { alc662_init_verbs },
16271 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16272 .dac_nids = alc662_dac_nids,
16273 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16274 .dig_in_nid = ALC662_DIGIN_NID,
16275 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16276 .channel_mode = alc662_3ST_6ch_modes,
16277 .need_dac_fix = 1,
16278 .input_mux = &alc662_capture_source,
f12ab1e0 16279 },
bc9f98a9 16280 [ALC662_3ST_6ch] = {
f9e336f6 16281 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16282 .init_verbs = { alc662_init_verbs },
16283 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16284 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16285 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16286 .channel_mode = alc662_3ST_6ch_modes,
16287 .need_dac_fix = 1,
16288 .input_mux = &alc662_capture_source,
f12ab1e0 16289 },
bc9f98a9 16290 [ALC662_5ST_DIG] = {
f9e336f6 16291 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16292 .init_verbs = { alc662_init_verbs },
16293 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16294 .dac_nids = alc662_dac_nids,
16295 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16296 .dig_in_nid = ALC662_DIGIN_NID,
16297 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16298 .channel_mode = alc662_5stack_modes,
16299 .input_mux = &alc662_capture_source,
16300 },
16301 [ALC662_LENOVO_101E] = {
f9e336f6 16302 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
16303 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16304 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16305 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16306 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16307 .channel_mode = alc662_3ST_2ch_modes,
16308 .input_mux = &alc662_lenovo_101e_capture_source,
16309 .unsol_event = alc662_lenovo_101e_unsol_event,
16310 .init_hook = alc662_lenovo_101e_all_automute,
16311 },
291702f0 16312 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 16313 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
16314 .init_verbs = { alc662_init_verbs,
16315 alc662_eeepc_sue_init_verbs },
16316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16317 .dac_nids = alc662_dac_nids,
291702f0
KY
16318 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16319 .channel_mode = alc662_3ST_2ch_modes,
16320 .input_mux = &alc662_eeepc_capture_source,
16321 .unsol_event = alc662_eeepc_unsol_event,
16322 .init_hook = alc662_eeepc_inithook,
16323 },
8c427226 16324 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 16325 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
16326 alc662_chmode_mixer },
16327 .init_verbs = { alc662_init_verbs,
16328 alc662_eeepc_ep20_sue_init_verbs },
16329 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16330 .dac_nids = alc662_dac_nids,
8c427226
KY
16331 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16332 .channel_mode = alc662_3ST_6ch_modes,
16333 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 16334 .unsol_event = alc662_eeepc_unsol_event,
8c427226
KY
16335 .init_hook = alc662_eeepc_ep20_inithook,
16336 },
f1d4e28b 16337 [ALC662_ECS] = {
f9e336f6 16338 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
16339 .init_verbs = { alc662_init_verbs,
16340 alc662_ecs_init_verbs },
16341 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16342 .dac_nids = alc662_dac_nids,
16343 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16344 .channel_mode = alc662_3ST_2ch_modes,
16345 .input_mux = &alc662_eeepc_capture_source,
16346 .unsol_event = alc662_eeepc_unsol_event,
16347 .init_hook = alc662_eeepc_inithook,
16348 },
6dda9f4a 16349 [ALC663_ASUS_M51VA] = {
f9e336f6 16350 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16351 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16352 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16353 .dac_nids = alc662_dac_nids,
16354 .dig_out_nid = ALC662_DIGOUT_NID,
16355 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16356 .channel_mode = alc662_3ST_2ch_modes,
16357 .input_mux = &alc663_m51va_capture_source,
16358 .unsol_event = alc663_m51va_unsol_event,
16359 .init_hook = alc663_m51va_inithook,
16360 },
16361 [ALC663_ASUS_G71V] = {
f9e336f6 16362 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
16363 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16364 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16365 .dac_nids = alc662_dac_nids,
16366 .dig_out_nid = ALC662_DIGOUT_NID,
16367 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16368 .channel_mode = alc662_3ST_2ch_modes,
16369 .input_mux = &alc662_eeepc_capture_source,
16370 .unsol_event = alc663_g71v_unsol_event,
16371 .init_hook = alc663_g71v_inithook,
16372 },
16373 [ALC663_ASUS_H13] = {
f9e336f6 16374 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16375 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16376 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16377 .dac_nids = alc662_dac_nids,
16378 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16379 .channel_mode = alc662_3ST_2ch_modes,
16380 .input_mux = &alc663_m51va_capture_source,
16381 .unsol_event = alc663_m51va_unsol_event,
16382 .init_hook = alc663_m51va_inithook,
16383 },
16384 [ALC663_ASUS_G50V] = {
f9e336f6 16385 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
16386 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16387 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16388 .dac_nids = alc662_dac_nids,
16389 .dig_out_nid = ALC662_DIGOUT_NID,
16390 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16391 .channel_mode = alc662_3ST_6ch_modes,
16392 .input_mux = &alc663_capture_source,
16393 .unsol_event = alc663_g50v_unsol_event,
16394 .init_hook = alc663_g50v_inithook,
16395 },
f1d4e28b 16396 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
16397 .mixers = { alc663_m51va_mixer },
16398 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16399 .init_verbs = { alc662_init_verbs,
16400 alc663_21jd_amic_init_verbs },
16401 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16402 .hp_nid = 0x03,
16403 .dac_nids = alc662_dac_nids,
16404 .dig_out_nid = ALC662_DIGOUT_NID,
16405 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16406 .channel_mode = alc662_3ST_2ch_modes,
16407 .input_mux = &alc662_eeepc_capture_source,
16408 .unsol_event = alc663_mode1_unsol_event,
16409 .init_hook = alc663_mode1_inithook,
16410 },
16411 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
16412 .mixers = { alc662_1bjd_mixer },
16413 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16414 .init_verbs = { alc662_init_verbs,
16415 alc662_1bjd_amic_init_verbs },
16416 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16417 .dac_nids = alc662_dac_nids,
16418 .dig_out_nid = ALC662_DIGOUT_NID,
16419 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16420 .channel_mode = alc662_3ST_2ch_modes,
16421 .input_mux = &alc662_eeepc_capture_source,
16422 .unsol_event = alc662_mode2_unsol_event,
16423 .init_hook = alc662_mode2_inithook,
16424 },
16425 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
16426 .mixers = { alc663_two_hp_m1_mixer },
16427 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16428 .init_verbs = { alc662_init_verbs,
16429 alc663_two_hp_amic_m1_init_verbs },
16430 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16431 .hp_nid = 0x03,
16432 .dac_nids = alc662_dac_nids,
16433 .dig_out_nid = ALC662_DIGOUT_NID,
16434 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16435 .channel_mode = alc662_3ST_2ch_modes,
16436 .input_mux = &alc662_eeepc_capture_source,
16437 .unsol_event = alc663_mode3_unsol_event,
16438 .init_hook = alc663_mode3_inithook,
16439 },
16440 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
16441 .mixers = { alc663_asus_21jd_clfe_mixer },
16442 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16443 .init_verbs = { alc662_init_verbs,
16444 alc663_21jd_amic_init_verbs},
16445 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16446 .hp_nid = 0x03,
16447 .dac_nids = alc662_dac_nids,
16448 .dig_out_nid = ALC662_DIGOUT_NID,
16449 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16450 .channel_mode = alc662_3ST_2ch_modes,
16451 .input_mux = &alc662_eeepc_capture_source,
16452 .unsol_event = alc663_mode4_unsol_event,
16453 .init_hook = alc663_mode4_inithook,
16454 },
16455 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
16456 .mixers = { alc663_asus_15jd_clfe_mixer },
16457 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16458 .init_verbs = { alc662_init_verbs,
16459 alc663_15jd_amic_init_verbs },
16460 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16461 .hp_nid = 0x03,
16462 .dac_nids = alc662_dac_nids,
16463 .dig_out_nid = ALC662_DIGOUT_NID,
16464 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16465 .channel_mode = alc662_3ST_2ch_modes,
16466 .input_mux = &alc662_eeepc_capture_source,
16467 .unsol_event = alc663_mode5_unsol_event,
16468 .init_hook = alc663_mode5_inithook,
16469 },
16470 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
16471 .mixers = { alc663_two_hp_m2_mixer },
16472 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16473 .init_verbs = { alc662_init_verbs,
16474 alc663_two_hp_amic_m2_init_verbs },
16475 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16476 .hp_nid = 0x03,
16477 .dac_nids = alc662_dac_nids,
16478 .dig_out_nid = ALC662_DIGOUT_NID,
16479 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16480 .channel_mode = alc662_3ST_2ch_modes,
16481 .input_mux = &alc662_eeepc_capture_source,
16482 .unsol_event = alc663_mode6_unsol_event,
16483 .init_hook = alc663_mode6_inithook,
16484 },
622e84cd
KY
16485 [ALC272_DELL] = {
16486 .mixers = { alc663_m51va_mixer },
16487 .cap_mixer = alc272_auto_capture_mixer,
16488 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16489 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16490 .dac_nids = alc662_dac_nids,
16491 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16492 .adc_nids = alc272_adc_nids,
16493 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16494 .capsrc_nids = alc272_capsrc_nids,
16495 .channel_mode = alc662_3ST_2ch_modes,
16496 .input_mux = &alc663_m51va_capture_source,
16497 .unsol_event = alc663_m51va_unsol_event,
16498 .init_hook = alc663_m51va_inithook,
16499 },
16500 [ALC272_DELL_ZM1] = {
16501 .mixers = { alc663_m51va_mixer },
16502 .cap_mixer = alc662_auto_capture_mixer,
16503 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16504 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16505 .dac_nids = alc662_dac_nids,
16506 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16507 .adc_nids = alc662_adc_nids,
16508 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16509 .capsrc_nids = alc662_capsrc_nids,
16510 .channel_mode = alc662_3ST_2ch_modes,
16511 .input_mux = &alc663_m51va_capture_source,
16512 .unsol_event = alc663_m51va_unsol_event,
16513 .init_hook = alc663_m51va_inithook,
16514 },
bc9f98a9
KY
16515};
16516
16517
16518/*
16519 * BIOS auto configuration
16520 */
16521
16522/* add playback controls from the parsed DAC table */
16523static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16524 const struct auto_pin_cfg *cfg)
16525{
16526 char name[32];
16527 static const char *chname[4] = {
16528 "Front", "Surround", NULL /*CLFE*/, "Side"
16529 };
16530 hda_nid_t nid;
16531 int i, err;
16532
16533 for (i = 0; i < cfg->line_outs; i++) {
16534 if (!spec->multiout.dac_nids[i])
16535 continue;
b60dd394 16536 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
16537 if (i == 2) {
16538 /* Center/LFE */
16539 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16540 "Center Playback Volume",
f12ab1e0
TI
16541 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16542 HDA_OUTPUT));
bc9f98a9
KY
16543 if (err < 0)
16544 return err;
16545 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16546 "LFE Playback Volume",
f12ab1e0
TI
16547 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16548 HDA_OUTPUT));
bc9f98a9
KY
16549 if (err < 0)
16550 return err;
b69ce01a 16551 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16552 "Center Playback Switch",
b69ce01a 16553 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 16554 HDA_INPUT));
bc9f98a9
KY
16555 if (err < 0)
16556 return err;
b69ce01a 16557 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16558 "LFE Playback Switch",
b69ce01a 16559 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 16560 HDA_INPUT));
bc9f98a9
KY
16561 if (err < 0)
16562 return err;
16563 } else {
16564 sprintf(name, "%s Playback Volume", chname[i]);
16565 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
16566 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16567 HDA_OUTPUT));
bc9f98a9
KY
16568 if (err < 0)
16569 return err;
16570 sprintf(name, "%s Playback Switch", chname[i]);
b69ce01a
HRK
16571 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16572 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16573 3, 0, HDA_INPUT));
bc9f98a9
KY
16574 if (err < 0)
16575 return err;
16576 }
16577 }
16578 return 0;
16579}
16580
16581/* add playback controls for speaker and HP outputs */
16582static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16583 const char *pfx)
16584{
16585 hda_nid_t nid;
16586 int err;
16587 char name[32];
16588
16589 if (!pin)
16590 return 0;
16591
24fb9173
TI
16592 if (pin == 0x17) {
16593 /* ALC663 has a mono output pin on 0x17 */
16594 sprintf(name, "%s Playback Switch", pfx);
16595 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16596 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16597 return err;
16598 }
16599
bc9f98a9
KY
16600 if (alc880_is_fixed_pin(pin)) {
16601 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
939778ae 16602 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
bc9f98a9
KY
16603 /* specify the DAC as the extra output */
16604 if (!spec->multiout.hp_nid)
16605 spec->multiout.hp_nid = nid;
16606 else
16607 spec->multiout.extra_out_nid[0] = nid;
16608 /* control HP volume/switch on the output mixer amp */
16609 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16610 sprintf(name, "%s Playback Volume", pfx);
16611 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16612 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16613 if (err < 0)
16614 return err;
16615 sprintf(name, "%s Playback Switch", pfx);
16616 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16617 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16618 if (err < 0)
16619 return err;
16620 } else if (alc880_is_multi_pin(pin)) {
16621 /* set manual connection */
16622 /* we have only a switch on HP-out PIN */
16623 sprintf(name, "%s Playback Switch", pfx);
16624 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16625 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16626 if (err < 0)
16627 return err;
16628 }
16629 return 0;
16630}
16631
2d864c49
TI
16632/* return the index of the src widget from the connection list of the nid.
16633 * return -1 if not found
16634 */
16635static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16636 hda_nid_t src)
16637{
16638 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16639 int i, conns;
16640
16641 conns = snd_hda_get_connections(codec, nid, conn_list,
16642 ARRAY_SIZE(conn_list));
16643 if (conns < 0)
16644 return -1;
16645 for (i = 0; i < conns; i++)
16646 if (conn_list[i] == src)
16647 return i;
16648 return -1;
16649}
16650
16651static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16652{
1327a32b 16653 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2d864c49
TI
16654 return (pincap & AC_PINCAP_IN) != 0;
16655}
16656
bc9f98a9 16657/* create playback/capture controls for input pins */
2d864c49 16658static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
bc9f98a9
KY
16659 const struct auto_pin_cfg *cfg)
16660{
2d864c49 16661 struct alc_spec *spec = codec->spec;
61b9b9b1 16662 struct hda_input_mux *imux = &spec->private_imux[0];
bc9f98a9
KY
16663 int i, err, idx;
16664
16665 for (i = 0; i < AUTO_PIN_LAST; i++) {
2d864c49
TI
16666 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16667 idx = alc662_input_pin_idx(codec, 0x0b,
16668 cfg->input_pins[i]);
16669 if (idx >= 0) {
16670 err = new_analog_input(spec, cfg->input_pins[i],
16671 auto_pin_cfg_labels[i],
16672 idx, 0x0b);
16673 if (err < 0)
16674 return err;
16675 }
16676 idx = alc662_input_pin_idx(codec, 0x22,
16677 cfg->input_pins[i]);
16678 if (idx >= 0) {
16679 imux->items[imux->num_items].label =
16680 auto_pin_cfg_labels[i];
16681 imux->items[imux->num_items].index = idx;
16682 imux->num_items++;
16683 }
bc9f98a9
KY
16684 }
16685 }
16686 return 0;
16687}
16688
16689static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16690 hda_nid_t nid, int pin_type,
16691 int dac_idx)
16692{
f6c7e546 16693 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
16694 /* need the manual connection? */
16695 if (alc880_is_multi_pin(nid)) {
16696 struct alc_spec *spec = codec->spec;
16697 int idx = alc880_multi_pin_idx(nid);
16698 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16699 AC_VERB_SET_CONNECT_SEL,
16700 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16701 }
16702}
16703
16704static void alc662_auto_init_multi_out(struct hda_codec *codec)
16705{
16706 struct alc_spec *spec = codec->spec;
16707 int i;
16708
16709 for (i = 0; i <= HDA_SIDE; i++) {
16710 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16711 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 16712 if (nid)
baba8ee9 16713 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
16714 i);
16715 }
16716}
16717
16718static void alc662_auto_init_hp_out(struct hda_codec *codec)
16719{
16720 struct alc_spec *spec = codec->spec;
16721 hda_nid_t pin;
16722
16723 pin = spec->autocfg.hp_pins[0];
16724 if (pin) /* connect to front */
16725 /* use dac 0 */
16726 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16727 pin = spec->autocfg.speaker_pins[0];
16728 if (pin)
16729 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
16730}
16731
bc9f98a9
KY
16732#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16733
16734static void alc662_auto_init_analog_input(struct hda_codec *codec)
16735{
16736 struct alc_spec *spec = codec->spec;
16737 int i;
16738
16739 for (i = 0; i < AUTO_PIN_LAST; i++) {
16740 hda_nid_t nid = spec->autocfg.input_pins[i];
2d864c49 16741 if (alc662_is_input_pin(codec, nid)) {
23f0c048 16742 alc_set_input_pin(codec, nid, i);
52ca15b7 16743 if (nid != ALC662_PIN_CD_NID &&
e82c025b 16744 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
16745 snd_hda_codec_write(codec, nid, 0,
16746 AC_VERB_SET_AMP_GAIN_MUTE,
16747 AMP_OUT_MUTE);
16748 }
16749 }
16750}
16751
f511b01c
TI
16752#define alc662_auto_init_input_src alc882_auto_init_input_src
16753
bc9f98a9
KY
16754static int alc662_parse_auto_config(struct hda_codec *codec)
16755{
16756 struct alc_spec *spec = codec->spec;
16757 int err;
16758 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16759
16760 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16761 alc662_ignore);
16762 if (err < 0)
16763 return err;
16764 if (!spec->autocfg.line_outs)
16765 return 0; /* can't find valid BIOS pin config */
16766
f12ab1e0
TI
16767 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16768 if (err < 0)
16769 return err;
16770 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16771 if (err < 0)
16772 return err;
16773 err = alc662_auto_create_extra_out(spec,
16774 spec->autocfg.speaker_pins[0],
16775 "Speaker");
16776 if (err < 0)
16777 return err;
16778 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16779 "Headphone");
16780 if (err < 0)
16781 return err;
2d864c49 16782 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
f12ab1e0 16783 if (err < 0)
bc9f98a9
KY
16784 return err;
16785
16786 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16787
0852d7a6 16788 if (spec->autocfg.dig_outs)
bc9f98a9
KY
16789 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16790
603c4019 16791 if (spec->kctls.list)
d88897ea 16792 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
16793
16794 spec->num_mux_defs = 1;
61b9b9b1 16795 spec->input_mux = &spec->private_imux[0];
ea1fb29a 16796
d88897ea 16797 add_verb(spec, alc662_auto_init_verbs);
24fb9173 16798 if (codec->vendor_id == 0x10ec0663)
d88897ea 16799 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
16800
16801 err = alc_auto_add_mic_boost(codec);
16802 if (err < 0)
16803 return err;
16804
4a79ba34
TI
16805 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16806
8c87286f 16807 return 1;
bc9f98a9
KY
16808}
16809
16810/* additional initialization for auto-configuration model */
16811static void alc662_auto_init(struct hda_codec *codec)
16812{
f6c7e546 16813 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
16814 alc662_auto_init_multi_out(codec);
16815 alc662_auto_init_hp_out(codec);
16816 alc662_auto_init_analog_input(codec);
f511b01c 16817 alc662_auto_init_input_src(codec);
f6c7e546 16818 if (spec->unsol_event)
7fb0d78f 16819 alc_inithook(codec);
bc9f98a9
KY
16820}
16821
16822static int patch_alc662(struct hda_codec *codec)
16823{
16824 struct alc_spec *spec;
16825 int err, board_config;
16826
16827 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16828 if (!spec)
16829 return -ENOMEM;
16830
16831 codec->spec = spec;
16832
2c3bf9ab
TI
16833 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16834
bc9f98a9
KY
16835 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16836 alc662_models,
16837 alc662_cfg_tbl);
16838 if (board_config < 0) {
16839 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16840 "trying auto-probe from BIOS...\n");
16841 board_config = ALC662_AUTO;
16842 }
16843
16844 if (board_config == ALC662_AUTO) {
16845 /* automatic parse from the BIOS config */
16846 err = alc662_parse_auto_config(codec);
16847 if (err < 0) {
16848 alc_free(codec);
16849 return err;
8c87286f 16850 } else if (!err) {
bc9f98a9
KY
16851 printk(KERN_INFO
16852 "hda_codec: Cannot set up configuration "
16853 "from BIOS. Using base mode...\n");
16854 board_config = ALC662_3ST_2ch_DIG;
16855 }
16856 }
16857
680cd536
KK
16858 err = snd_hda_attach_beep_device(codec, 0x1);
16859 if (err < 0) {
16860 alc_free(codec);
16861 return err;
16862 }
16863
bc9f98a9
KY
16864 if (board_config != ALC662_AUTO)
16865 setup_preset(spec, &alc662_presets[board_config]);
16866
6dda9f4a
KY
16867 if (codec->vendor_id == 0x10ec0663) {
16868 spec->stream_name_analog = "ALC663 Analog";
16869 spec->stream_name_digital = "ALC663 Digital";
01afd41f
KY
16870 } else if (codec->vendor_id == 0x10ec0272) {
16871 spec->stream_name_analog = "ALC272 Analog";
16872 spec->stream_name_digital = "ALC272 Digital";
6dda9f4a
KY
16873 } else {
16874 spec->stream_name_analog = "ALC662 Analog";
16875 spec->stream_name_digital = "ALC662 Digital";
16876 }
16877
bc9f98a9
KY
16878 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16879 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16880
bc9f98a9
KY
16881 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16882 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16883
e1406348
TI
16884 spec->adc_nids = alc662_adc_nids;
16885 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16886 spec->capsrc_nids = alc662_capsrc_nids;
61b9b9b1 16887 spec->capture_style = CAPT_MIX;
bc9f98a9 16888
f9e336f6
TI
16889 if (!spec->cap_mixer)
16890 set_capture_mixer(spec);
b9591448
TI
16891 if (codec->vendor_id == 0x10ec0662)
16892 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16893 else
16894 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f9e336f6 16895
2134ea4f
TI
16896 spec->vmaster_nid = 0x02;
16897
bc9f98a9
KY
16898 codec->patch_ops = alc_patch_ops;
16899 if (board_config == ALC662_AUTO)
16900 spec->init_hook = alc662_auto_init;
cb53c626
TI
16901#ifdef CONFIG_SND_HDA_POWER_SAVE
16902 if (!spec->loopback.amplist)
16903 spec->loopback.amplist = alc662_loopbacks;
16904#endif
daead538 16905 codec->proc_widget_hook = print_realtek_coef;
bc9f98a9
KY
16906
16907 return 0;
16908}
16909
1da177e4
LT
16910/*
16911 * patch entries
16912 */
1289e9e8 16913static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 16914 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 16915 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 16916 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 16917 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 16918 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 16919 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 16920 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 16921 .patch = patch_alc861 },
f32610ed
JS
16922 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16923 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16924 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
16925 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16926 .patch = patch_alc883 },
16927 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16928 .patch = patch_alc662 },
6dda9f4a 16929 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 16930 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 16931 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 16932 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
669faba2
CM
16933 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16934 .patch = patch_alc882 }, /* should be patch_alc883() in future */
cb308f97 16935 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 16936 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 16937 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
a385a529 16938 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
4442608d
KY
16939 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16940 .patch = patch_alc883 },
3fea2cb0 16941 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 16942 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
16943 {} /* terminator */
16944};
1289e9e8
TI
16945
16946MODULE_ALIAS("snd-hda-codec-id:10ec*");
16947
16948MODULE_LICENSE("GPL");
16949MODULE_DESCRIPTION("Realtek HD-audio codec");
16950
16951static struct hda_codec_preset_list realtek_list = {
16952 .preset = snd_hda_preset_realtek,
16953 .owner = THIS_MODULE,
16954};
16955
16956static int __init patch_realtek_init(void)
16957{
16958 return snd_hda_add_codec_preset(&realtek_list);
16959}
16960
16961static void __exit patch_realtek_exit(void)
16962{
16963 snd_hda_delete_codec_preset(&realtek_list);
16964}
16965
16966module_init(patch_realtek_init)
16967module_exit(patch_realtek_exit)